diff --git a/authenticate/handlers.go b/authenticate/handlers.go index 351ea5192..ca5afe92b 100644 --- a/authenticate/handlers.go +++ b/authenticate/handlers.go @@ -84,6 +84,7 @@ func (a *Authenticate) mountDashboard(r *mux.Router) { AllowedHeaders: []string{"*"}, }) sr.Use(c.Handler) + sr.Use(a.RetrieveSession) // routes that don't need a session: sr.Path("/sign_out").Handler(httputil.HandlerFunc(a.SignOut)) @@ -91,7 +92,6 @@ func (a *Authenticate) mountDashboard(r *mux.Router) { // routes that need a session: sr = sr.NewRoute().Subrouter() - sr.Use(a.RetrieveSession) sr.Use(a.VerifySession) sr.Path("/").Handler(a.requireValidSignatureOnRedirect(a.userInfo)) sr.Path("/sign_in").Handler(httputil.HandlerFunc(a.SignIn)) @@ -475,7 +475,9 @@ func (a *Authenticate) revokeSession(ctx context.Context, w http.ResponseWriter, return "" } - return state.flow.RevokeSession(ctx, r, authenticator, nil) + sessionState, _ := a.getSessionFromCtx(ctx) + + return state.flow.RevokeSession(ctx, r, authenticator, sessionState) } // Callback handles the result of a successful call to the authenticate service diff --git a/authenticate/state.go b/authenticate/state.go index 213060e11..f8db3960d 100644 --- a/authenticate/state.go +++ b/authenticate/state.go @@ -144,13 +144,17 @@ func newAuthenticateStateFromConfig( } } - state.flow, err = authenticateflow.NewStateless( - cfg, - cookieStore, - authenticateConfig.getIdentityProvider, - authenticateConfig.profileTrimFn, - authenticateConfig.authEventFn, - ) + if cfg.Options.UseStatelessAuthenticateFlow() { + state.flow, err = authenticateflow.NewStateless( + cfg, + cookieStore, + authenticateConfig.getIdentityProvider, + authenticateConfig.profileTrimFn, + authenticateConfig.authEventFn, + ) + } else { + state.flow, err = authenticateflow.NewStateful(cfg, cookieStore) + } if err != nil { return nil, err } diff --git a/authorize/state.go b/authorize/state.go index bb2d9e277..115b0bea2 100644 --- a/authorize/state.go +++ b/authorize/state.go @@ -83,7 +83,11 @@ func newAuthorizeStateFromConfig( return nil, fmt.Errorf("authorize: invalid session store: %w", err) } - state.authenticateFlow, err = authenticateflow.NewStateless(cfg, nil, nil, nil, nil) + if cfg.Options.UseStatelessAuthenticateFlow() { + state.authenticateFlow, err = authenticateflow.NewStateless(cfg, nil, nil, nil, nil) + } else { + state.authenticateFlow, err = authenticateflow.NewStateful(cfg, nil) + } if err != nil { return nil, err } diff --git a/config/options.go b/config/options.go index f329ad39b..0a82caa16 100644 --- a/config/options.go +++ b/config/options.go @@ -827,6 +827,16 @@ func (o *Options) GetInternalAuthenticateURL() (*url.URL, error) { return urlutil.ParseAndValidateURL(o.AuthenticateInternalURLString) } +// UseStatelessAuthenticateFlow returns true if the stateless authentication +// flow should be used (i.e. for hosted authenticate). +func (o *Options) UseStatelessAuthenticateFlow() bool { + u, err := o.GetInternalAuthenticateURL() + if err != nil { + return false + } + return urlutil.IsHostedAuthenticateDomain(u.Hostname()) +} + // GetAuthorizeURLs returns the AuthorizeURLs in the options or 127.0.0.1:5443. func (o *Options) GetAuthorizeURLs() ([]*url.URL, error) { if IsAll(o.Services) && o.AuthorizeURLString == "" && len(o.AuthorizeURLStrings) == 0 { diff --git a/config/options_test.go b/config/options_test.go index 39e9b753a..4801e14c8 100644 --- a/config/options_test.go +++ b/config/options_test.go @@ -856,6 +856,21 @@ func TestOptions_DefaultURL(t *testing.T) { } } +func TestOptions_UseStatelessAuthenticateFlow(t *testing.T) { + t.Run("enabled by default", func(t *testing.T) { + options := &Options{} + assert.True(t, options.UseStatelessAuthenticateFlow()) + }) + t.Run("enabled explicitly", func(t *testing.T) { + options := &Options{AuthenticateURLString: "https://authenticate.pomerium.app"} + assert.True(t, options.UseStatelessAuthenticateFlow()) + }) + t.Run("disabled", func(t *testing.T) { + options := &Options{AuthenticateURLString: "https://authenticate.example.com"} + assert.False(t, options.UseStatelessAuthenticateFlow()) + }) +} + func TestOptions_GetOauthOptions(t *testing.T) { opts := &Options{AuthenticateURLString: "https://authenticate.example.com"} oauthOptions, err := opts.GetOauthOptions() diff --git a/proxy/state.go b/proxy/state.go index bdb4b1a64..42f8ebb44 100644 --- a/proxy/state.go +++ b/proxy/state.go @@ -114,8 +114,12 @@ func newProxyStateFromConfig(cfg *config.Config) (*proxyState, error) { state.programmaticRedirectDomainWhitelist = cfg.Options.ProgrammaticRedirectDomainWhitelist - state.authenticateFlow, err = authenticateflow.NewStateless( - cfg, state.sessionStore, nil, nil, nil) + if cfg.Options.UseStatelessAuthenticateFlow() { + state.authenticateFlow, err = authenticateflow.NewStateless( + cfg, state.sessionStore, nil, nil, nil) + } else { + state.authenticateFlow, err = authenticateflow.NewStateful(cfg, state.sessionStore) + } if err != nil { return nil, err }