@@ -134,36 +134,6 @@ type signInResp struct {
134134 Version string
135135}
136136
137- // SignInPage directs the user to the sign in page
138- func (p * Authenticator ) SignInPage (rw http.ResponseWriter , req * http.Request , code int ) {
139- rw .WriteHeader (code )
140-
141- // We construct this URL based on the known callback URL that we send to Google.
142- // We don't want to rely on req.Host, as that can be attacked via Host header injection
143- // This ends up looking like:
144- // https://sso-auth.example.com/sign_in?client_id=...&redirect_uri=...
145- path := strings .TrimPrefix (req .URL .Path , "/" )
146- redirectURL := p .redirectURL .ResolveReference (
147- & url.URL {
148- Path : path ,
149- RawQuery : req .URL .RawQuery ,
150- },
151- )
152-
153- // validateRedirectURI middleware already ensures that this is a valid URL
154- destinationURL , _ := url .Parse (redirectURL .Query ().Get ("redirect_uri" ))
155-
156- t := signInResp {
157- ProviderName : p .provider .Data ().ProviderName ,
158- ProviderSlug : p .provider .Data ().ProviderSlug ,
159- EmailDomains : p .EmailDomains ,
160- Redirect : redirectURL .String (),
161- Destination : destinationURL .Host ,
162- Version : VERSION ,
163- }
164- p .templates .ExecuteTemplate (rw , "sign_in.html" , t )
165- }
166-
167137func (p * Authenticator ) authenticate (rw http.ResponseWriter , req * http.Request ) (* sessions.SessionState , error ) {
168138 logger := log .NewLogEntry ()
169139 remoteAddr := getRemoteAddr (req )
@@ -257,20 +227,36 @@ func (p *Authenticator) SignIn(rw http.ResponseWriter, req *http.Request) {
257227 "action:sign_in" ,
258228 fmt .Sprintf ("proxy_host:%s" , proxyHost ),
259229 }
230+
231+ // We construct this URL based on the known callback URL that we send to Google.
232+ // We don't want to rely on req.Host, as that can be attacked via Host header injection
233+ // This ends up looking like:
234+ // https://sso-auth.example.com/sign_in?client_id=...&redirect_uri=...
235+ //
236+ // The validateRedirectURI middleware ensures that this is a valid URL
237+ path := strings .TrimPrefix (req .URL .Path , "/" )
238+ redirectURL := p .redirectURL .ResolveReference (
239+ & url.URL {
240+ Path : path ,
241+ RawQuery : req .URL .RawQuery ,
242+ },
243+ )
244+ req .URL = redirectURL
245+
260246 session , err := p .authenticate (rw , req )
261247 switch err {
262248 case nil :
263249 // User is authenticated, redirect back to the proxy application
264250 // with the necessary state
265251 p .ProxyOAuthRedirect (rw , req , session , tags )
266252 case http .ErrNoCookie :
267- p .SignInPage (rw , req , http . StatusOK )
253+ p .OAuthStart (rw , req )
268254 case providers .ErrTokenRevoked :
269255 p .sessionStore .ClearSession (rw , req )
270- p .SignInPage (rw , req , http . StatusOK )
256+ p .OAuthStart (rw , req )
271257 case sessions .ErrLifetimeExpired , sessions .ErrInvalidSession :
272258 p .sessionStore .ClearSession (rw , req )
273- p .SignInPage (rw , req , http . StatusOK )
259+ p .OAuthStart (rw , req )
274260 default :
275261 tags = append (tags , "error:sign_in_error" )
276262 p .StatsdClient .Incr ("application_error" , tags , 1.0 )
@@ -373,17 +359,13 @@ func (p *Authenticator) SignOut(rw http.ResponseWriter, req *http.Request) {
373359 fmt .Sprintf ("proxy_host:%s" , proxyHost ),
374360 }
375361
376- if req .Method == "GET" {
377- p .SignOutPage (rw , req , "" )
378- return
379- }
380-
381362 session , err := p .sessionStore .LoadSession (req )
382363 switch err {
383364 case nil :
365+ // no error - we were able to load the session. continue onwards.
384366 break
385- // if there's no cookie in the session we can just redirect
386367 case http .ErrNoCookie :
368+ // if there's no session, we can just redirect back.
387369 http .Redirect (rw , req , redirectURI , http .StatusFound )
388370 return
389371 default :
@@ -399,95 +381,49 @@ func (p *Authenticator) SignOut(rw http.ResponseWriter, req *http.Request) {
399381 tags = append (tags , "error:revoke_session" )
400382 p .StatsdClient .Incr ("provider_error" , tags , 1.0 )
401383 logger .Error (err , "error revoking session" )
402- p .SignOutPage (rw , req , "An error occurred during sign out. Please try again." )
384+ //TODO: This used to return a sign out page with an error.
385+ //TODO: http.StatusInternalServerError or codeForError(err)
386+ p .ErrorResponse (rw , req , err .Error (), http .StatusInternalServerError )
403387 return
404388 }
405389
390+ // if we reach here, the session has been revoked on the identity providers end,
391+ // clear our session and redirect.
406392 p .sessionStore .ClearSession (rw , req )
407393 http .Redirect (rw , req , redirectURI , http .StatusFound )
408394}
409395
410- type signOutResp struct {
411- ProviderSlug string
412- Version string
413- Redirect string
414- Signature string
415- Timestamp string
416- Message string
417- Destination string
418- Email string
419- }
420-
421- // SignOutPage renders a sign out page with a message
422- func (p * Authenticator ) SignOutPage (rw http.ResponseWriter , req * http.Request , message string ) {
423- // validateRedirectURI middleware already ensures that this is a valid URL
424- redirectURI := req .Form .Get ("redirect_uri" )
425-
426- session , err := p .sessionStore .LoadSession (req )
427- if err != nil {
428- http .Redirect (rw , req , redirectURI , http .StatusFound )
429- return
430- }
431-
432- signature := req .Form .Get ("sig" )
433- timestamp := req .Form .Get ("ts" )
434- destinationURL , _ := url .Parse (redirectURI )
435-
436- // An error message indicates that an internal server error occurred
437- if message != "" {
438- rw .WriteHeader (http .StatusInternalServerError )
439- }
440-
441- t := signOutResp {
442- ProviderSlug : p .provider .Data ().ProviderSlug ,
443- Version : VERSION ,
444- Redirect : redirectURI ,
445- Signature : signature ,
446- Timestamp : timestamp ,
447- Message : message ,
448- Destination : destinationURL .Host ,
449- Email : session .Email ,
450- }
451- p .templates .ExecuteTemplate (rw , "sign_out.html" , t )
452- return
453- }
454-
455396// OAuthStart starts the authentication process by redirecting to the provider. It provides a
456397// `redirectURI`, allowing the provider to redirect back to the sso proxy after authentication.
457398func (p * Authenticator ) OAuthStart (rw http.ResponseWriter , req * http.Request ) {
458399 tags := []string {"action:start" }
459400
460401 nonce := fmt .Sprintf ("%x" , aead .GenerateKey ())
461402 p .csrfStore .SetCSRF (rw , req , nonce )
462- authRedirectURL , err := url .Parse (req .URL .Query ().Get ("redirect_uri" ))
463- if err != nil || ! validRedirectURI (authRedirectURL .String (), p .ProxyRootDomains ) {
464- tags = append (tags , "error:invalid_redirect_parameter" )
465- p .StatsdClient .Incr ("application_error" , tags , 1.0 )
466- p .ErrorResponse (rw , req , "Invalid redirect parameter" , http .StatusBadRequest )
467- return
468- }
403+
469404 // Here we validate the redirect that is nested within the redirect_uri.
470405 // `authRedirectURL` points to step D, `proxyRedirectURL` points to step E.
471406 //
472407 // A* B C D E
473408 // /start -> Google -> auth /callback -> /sign_in -> proxy /callback
474409 //
475410 // * you are here
476- proxyRedirectURL , err := url .Parse (authRedirectURL .Query ().Get ("redirect_uri" ))
411+
412+ proxyRedirectURL , err := url .Parse (req .URL .Query ().Get ("redirect_uri" ))
477413 if err != nil || ! validRedirectURI (proxyRedirectURL .String (), p .ProxyRootDomains ) {
478414 tags = append (tags , "error:invalid_redirect_parameter" )
479415 p .StatsdClient .Incr ("application_error" , tags , 1.0 )
480416 p .ErrorResponse (rw , req , "Invalid redirect parameter" , http .StatusBadRequest )
481417 return
482418 }
483- proxyRedirectSig := authRedirectURL .Query ().Get ("sig" )
484- ts := authRedirectURL .Query ().Get ("ts" )
419+ proxyRedirectSig := req . URL .Query ().Get ("sig" )
420+ ts := req . URL .Query ().Get ("ts" )
485421 if ! validSignature (proxyRedirectURL .String (), proxyRedirectSig , ts , p .ProxyClientSecret ) {
486422 p .ErrorResponse (rw , req , "Invalid redirect parameter" , http .StatusBadRequest )
487423 return
488424 }
489425 redirectURI := p .GetRedirectURI (req .Host )
490- state := base64 .URLEncoding .EncodeToString ([]byte (fmt .Sprintf ("%v:%v" , nonce , authRedirectURL .String ())))
426+ state := base64 .URLEncoding .EncodeToString ([]byte (fmt .Sprintf ("%v:%v" , nonce , req . URL .String ())))
491427 signInURL := p .provider .GetSignInURL (redirectURI , state )
492428 http .Redirect (rw , req , signInURL , http .StatusFound )
493429}
0 commit comments