Skip to content

Commit

Permalink
Per-client access token expiration
Browse files Browse the repository at this point in the history
  • Loading branch information
liggitt committed Jul 13, 2017
1 parent c52694b commit 6f1b7b4
Show file tree
Hide file tree
Showing 17 changed files with 196 additions and 89 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions api/swagger-spec/oapi-v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -29265,6 +29265,11 @@
"$ref": "v1.ScopeRestriction"
},
"description": "ScopeRestrictions describes which scopes this client can request. Each requested scope is checked against each restriction. If any restriction matches, then the scope is allowed. If no restriction matches, then the scope is denied."
},
"accessTokenMaxAgeSeconds": {
"type": "integer",
"format": "int32",
"description": "AccessTokenMaxAgeSeconds overrides the default access token max age for tokens granted to this client. 0 means no expiration."
}
}
},
Expand Down
5 changes: 5 additions & 0 deletions api/swagger-spec/openshift-openapi-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -85249,6 +85249,11 @@
"com.github.openshift.origin.pkg.oauth.apis.oauth.v1.OAuthClient": {
"description": "OAuthClient describes an OAuth client",
"properties": {
"accessTokenMaxAgeSeconds": {
"description": "AccessTokenMaxAgeSeconds overrides the default access token max age for tokens granted to this client. 0 means no expiration.",
"type": "integer",
"format": "int32"
},
"additionalSecrets": {
"description": "AdditionalSecrets holds other secrets that may be used to identify the client. This is useful for rotation and for service account token validation",
"type": "array",
Expand Down
14 changes: 14 additions & 0 deletions pkg/auth/oauth/handlers/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ func NewAuthorizeAuthenticator(request authenticator.Request, handler Authentica
return &AuthorizeAuthenticator{request, handler, errorHandler}
}

type TokenMaxAgeSeconds interface {
// GetTokenMaxAgeSeconds returns the max age of the token in seconds.
// 0 means no expiration.
// nil means to use the default expiration.
GetTokenMaxAgeSeconds() *int32
}

// HandleAuthorize implements osinserver.AuthorizeHandler to ensure the AuthorizeRequest is authenticated.
// If the request is authenticated, UserData and Authorized are set and false is returned.
// If the request is not authenticated, the auth handler is called and the request is not authorized
Expand All @@ -38,6 +45,13 @@ func (h *AuthorizeAuthenticator) HandleAuthorize(ar *osin.AuthorizeRequest, resp
glog.V(4).Infof("OAuth authentication succeeded: %#v", info)
ar.UserData = info
ar.Authorized = true

if e, ok := ar.Client.(TokenMaxAgeSeconds); ok {
if maxAge := e.GetTokenMaxAgeSeconds(); maxAge != nil {
ar.Expiration = *maxAge
}
}

return false, nil
}

Expand Down
6 changes: 4 additions & 2 deletions pkg/auth/oauth/registry/tokenauthenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ func (a *TokenAuthenticator) AuthenticateToken(value string) (kuser.Info, bool,
if err != nil {
return nil, false, err
}
if token.CreationTimestamp.Time.Add(time.Duration(token.ExpiresIn) * time.Second).Before(time.Now()) {
return nil, false, ErrExpired
if token.ExpiresIn > 0 {
if token.CreationTimestamp.Time.Add(time.Duration(token.ExpiresIn) * time.Second).Before(time.Now()) {
return nil, false, ErrExpired
}
}
if token.DeletionTimestamp != nil {
return nil, false, ErrExpired
Expand Down
8 changes: 6 additions & 2 deletions pkg/cmd/cli/describe/describer.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,12 +516,16 @@ func (d *OAuthAccessTokenDescriber) Describe(namespace, name string, settings kp
}

var timeCreated time.Time = oAuthAccessToken.ObjectMeta.CreationTimestamp.Time
var timeExpired time.Time = timeCreated.Add(time.Duration(oAuthAccessToken.ExpiresIn) * time.Second)
expires := "never"
if oAuthAccessToken.ExpiresIn > 0 {
var timeExpired time.Time = timeCreated.Add(time.Duration(oAuthAccessToken.ExpiresIn) * time.Second)
expires = formatToHumanDuration(timeExpired.Sub(time.Now()))
}

return tabbedString(func(out *tabwriter.Writer) error {
formatMeta(out, oAuthAccessToken.ObjectMeta)
formatString(out, "Scopes", oAuthAccessToken.Scopes)
formatString(out, "Expires In", formatToHumanDuration(timeExpired.Sub(time.Now())))
formatString(out, "Expires In", expires)
formatString(out, "User Name", oAuthAccessToken.UserName)
formatString(out, "User UID", oAuthAccessToken.UserUID)
formatString(out, "Client Name", oAuthAccessToken.ClientName)
Expand Down
5 changes: 4 additions & 1 deletion pkg/cmd/cli/describe/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,10 @@ func printOAuthClientAuthorizationList(list *oauthapi.OAuthClientAuthorizationLi
func printOAuthAccessToken(token *oauthapi.OAuthAccessToken, w io.Writer, opts kprinters.PrintOptions) error {
name := formatResourceName(opts.Kind, token.Name, opts.WithKind)
created := token.CreationTimestamp
expires := created.Add(time.Duration(token.ExpiresIn) * time.Second)
expires := "never"
if token.ExpiresIn > 0 {
expires = created.Add(time.Duration(token.ExpiresIn) * time.Second).String()
}
_, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", name, token.UserName, token.ClientName, created, expires, token.RedirectURI, strings.Join(token.Scopes, ","))
return err
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/oauth/apis/oauth/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ type OAuthClient struct {
// is checked against each restriction. If any restriction matches, then the scope is allowed.
// If no restriction matches, then the scope is denied.
ScopeRestrictions []ScopeRestriction

// AccessTokenMaxAgeSeconds overrides the default access token max age for tokens granted to this client.
// 0 means no expiration.
AccessTokenMaxAgeSeconds *int32
}

type GrantHandlerType string
Expand Down
Loading

0 comments on commit 6f1b7b4

Please sign in to comment.