X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/f0d3eae5fc05aaad38a2998627c59637e3ef606c..cac9d1111f86a7ff6da2176e3069dec4484154d4:/lib/controller/localdb/login_oidc.go diff --git a/lib/controller/localdb/login_oidc.go b/lib/controller/localdb/login_oidc.go index 1fa4da7766..74b8929a21 100644 --- a/lib/controller/localdb/login_oidc.go +++ b/lib/controller/localdb/login_oidc.go @@ -37,10 +37,11 @@ import ( "google.golang.org/api/people/v1" ) -const ( +var ( tokenCacheSize = 1000 tokenCacheNegativeTTL = time.Minute * 5 tokenCacheTTL = time.Minute * 10 + tokenCacheRaceWindow = time.Minute ) type oidcLoginController struct { @@ -49,10 +50,11 @@ type oidcLoginController struct { Issuer string // OIDC issuer URL, e.g., "https://accounts.google.com" ClientID string ClientSecret string - UseGooglePeopleAPI bool // Use Google People API to look up alternate email addresses - EmailClaim string // OpenID claim to use as email address; typically "email" - EmailVerifiedClaim string // If non-empty, ensure claim value is true before accepting EmailClaim; typically "email_verified" - UsernameClaim string // If non-empty, use as preferred username + UseGooglePeopleAPI bool // Use Google People API to look up alternate email addresses + EmailClaim string // OpenID claim to use as email address; typically "email" + EmailVerifiedClaim string // If non-empty, ensure claim value is true before accepting EmailClaim; typically "email_verified" + UsernameClaim string // If non-empty, use as preferred username + AuthParams map[string]string // Additional parameters to pass with authentication request // override Google People API base URL for testing purposes // (normally empty, set by google pkg to @@ -110,14 +112,12 @@ func (ctrl *oidcLoginController) Login(ctx context.Context, opts arvados.LoginOp return loginError(errors.New("missing return_to parameter")) } state := ctrl.newOAuth2State([]byte(ctrl.Cluster.SystemRootToken), opts.Remote, opts.ReturnTo) + var authparams []oauth2.AuthCodeOption + for k, v := range ctrl.AuthParams { + authparams = append(authparams, oauth2.SetAuthURLParam(k, v)) + } return arvados.LoginResponse{ - RedirectLocation: ctrl.oauth2conf.AuthCodeURL(state.String(), - // prompt=select_account tells Google - // to show the "choose which Google - // account" page, even if the client - // is currently logged in to exactly - // one Google account. - oauth2.SetAuthURLParam("prompt", "select_account")), + RedirectLocation: ctrl.oauth2conf.AuthCodeURL(state.String(), authparams...), }, nil } // Callback after OIDC sign-in. @@ -176,7 +176,7 @@ func (ctrl *oidcLoginController) getAuthInfo(ctx context.Context, token *oauth2. if names := strings.Fields(strings.TrimSpace(name)); len(names) > 1 { ret.FirstName = strings.Join(names[0:len(names)-1], " ") ret.LastName = names[len(names)-1] - } else { + } else if len(names) > 0 { ret.FirstName = names[0] } ret.Email, _ = claims[ctrl.EmailClaim].(string) @@ -363,8 +363,9 @@ func (ta *oidcTokenAuthorizer) WrapCalls(origFunc api.RoutableFunc) api.Routable return origFunc(ctx, opts) } // Check each token in the incoming request. If any - // are OAuth2 access tokens, swap them out for Arvados - // tokens. + // are valid OAuth2 access tokens, insert/update them + // in the database so RailsAPI's auth code accepts + // them. for _, tok := range creds.Tokens { err = ta.registerToken(ctx, tok) if err != nil { @@ -463,7 +464,7 @@ func (ta *oidcTokenAuthorizer) registerToken(ctx context.Context, tok string) er // Expiry time for our token is one minute longer than our // cache TTL, so we don't pass it through to RailsAPI just as // it's expiring. - exp := time.Now().UTC().Add(tokenCacheTTL + time.Minute) + exp := time.Now().UTC().Add(tokenCacheTTL + tokenCacheRaceWindow) var aca arvados.APIClientAuthorization if updating {