From 356aa33970dd1893ff0932cb4782131eb30f1a27 Mon Sep 17 00:00:00 2001 From: Michael Barrientos Date: Tue, 15 Jan 2019 20:20:00 -0800 Subject: [PATCH] Add SKIP_PROVIDER_BUTTON env --- authenticate/authenticate.go | 32 ++++++++++++++++++-------------- authenticate/handlers.go | 28 ++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/authenticate/authenticate.go b/authenticate/authenticate.go index a741ea898..fc9fd4454 100644 --- a/authenticate/authenticate.go +++ b/authenticate/authenticate.go @@ -48,11 +48,12 @@ type Options struct { SessionLifetimeTTL time.Duration `envconfig:"SESSION_LIFETIME_TTL"` // Authentication provider configuration vars - ClientID string `envconfig:"IDP_CLIENT_ID"` // IdP ClientID - ClientSecret string `envconfig:"IDP_CLIENT_SECRET"` // IdP Secret - Provider string `envconfig:"IDP_PROVIDER"` //Provider name e.g. "oidc","okta","google",etc - ProviderURL string `envconfig:"IDP_PROVIDER_URL"` - Scopes []string `envconfig:"IDP_SCOPE" default:"openid,email,profile"` + ClientID string `envconfig:"IDP_CLIENT_ID"` // IdP ClientID + ClientSecret string `envconfig:"IDP_CLIENT_SECRET"` // IdP Secret + Provider string `envconfig:"IDP_PROVIDER"` //Provider name e.g. "oidc","okta","google",etc + ProviderURL string `envconfig:"IDP_PROVIDER_URL"` + Scopes []string `envconfig:"IDP_SCOPE" default:"openid,email,profile"` + SkipProviderButton bool `envconfig:"SKIP_PROVIDER_BUTTON"` } // OptionsFromEnvConfig builds the authentication service's configuration @@ -122,6 +123,8 @@ type Authenticate struct { sessionStore sessions.SessionStore cipher cryptutil.Cipher + skipProviderButton bool + provider providers.Provider } @@ -160,15 +163,16 @@ func New(opts *Options, optionFuncs ...func(*Authenticate) error) (*Authenticate } p := &Authenticate{ - SharedKey: opts.SharedKey, - AllowedDomains: opts.AllowedDomains, - ProxyRootDomains: dotPrependDomains(opts.ProxyRootDomains), - CookieSecure: opts.CookieSecure, - RedirectURL: opts.RedirectURL, - templates: templates.New(), - csrfStore: cookieStore, - sessionStore: cookieStore, - cipher: cipher, + SharedKey: opts.SharedKey, + AllowedDomains: opts.AllowedDomains, + ProxyRootDomains: dotPrependDomains(opts.ProxyRootDomains), + CookieSecure: opts.CookieSecure, + RedirectURL: opts.RedirectURL, + templates: templates.New(), + csrfStore: cookieStore, + sessionStore: cookieStore, + cipher: cipher, + skipProviderButton: opts.SkipProviderButton, } // p.ServeMux = p.Handler() p.provider, err = newProvider(opts) diff --git a/authenticate/handlers.go b/authenticate/handlers.go index 19ef3e643..9ba85c6b5 100644 --- a/authenticate/handlers.go +++ b/authenticate/handlers.go @@ -191,11 +191,19 @@ func (p *Authenticate) SignIn(rw http.ResponseWriter, req *http.Request) { p.ProxyOAuthRedirect(rw, req, session) case http.ErrNoCookie: log.Error().Err(err).Msg("authenticate.SignIn : err no cookie") - p.SignInPage(rw, req) + if p.skipProviderButton { + p.skipButtonOAuthStart(rw, req) + } else { + p.SignInPage(rw, req) + } case sessions.ErrLifetimeExpired, sessions.ErrInvalidSession: log.Error().Err(err).Msg("authenticate.SignIn : invalid cookie cookie") p.sessionStore.ClearSession(rw, req) - p.SignInPage(rw, req) + if p.skipProviderButton { + p.skipButtonOAuthStart(rw, req) + } else { + p.SignInPage(rw, req) + } default: log.Error().Err(err).Msg("authenticate.SignIn : unknown error cookie") httputil.ErrorResponse(rw, req, err.Error(), httputil.CodeForError(err)) @@ -338,12 +346,24 @@ func (p *Authenticate) SignOutPage(rw http.ResponseWriter, req *http.Request, me // OAuthStart starts the authentication process by redirecting to the provider. It provides a // `redirectURI`, allowing the provider to redirect back to the sso proxy after authentication. func (p *Authenticate) OAuthStart(rw http.ResponseWriter, req *http.Request) { + authRedirectURL, err := url.Parse(req.URL.Query().Get("redirect_uri")) + if err == nil { + httputil.ErrorResponse(rw, req, "Invalid redirect parameter", http.StatusBadRequest) + return + } + p.helperOAuthStart(rw, req, authRedirectURL) +} + +func (p *Authenticate) skipButtonOAuthStart(rw http.ResponseWriter, req *http.Request) { + p.helperOAuthStart(rw, req, p.RedirectURL.ResolveReference(req.URL)) +} + +func (p *Authenticate) helperOAuthStart(rw http.ResponseWriter, req *http.Request, authRedirectURL *url.URL) { nonce := fmt.Sprintf("%x", cryptutil.GenerateKey()) p.csrfStore.SetCSRF(rw, req, nonce) - authRedirectURL, err := url.Parse(req.URL.Query().Get("redirect_uri")) - if err != nil || !validRedirectURI(authRedirectURL.String(), p.ProxyRootDomains) { + if !validRedirectURI(authRedirectURL.String(), p.ProxyRootDomains) { httputil.ErrorResponse(rw, req, "Invalid redirect parameter", http.StatusBadRequest) return }