outposts/proxy: always redirect to session-end interface on sign_out

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-07-01 15:48:56 +02:00
parent 6064a481fb
commit 4709dca33c
4 changed files with 39 additions and 32 deletions

View File

@ -29,9 +29,10 @@ func (s *Server) bundleProviders(providers []api.ProxyOutpostConfig) []*provider
log.WithError(err).Warning("Failed to parse URL, skipping provider") log.WithError(err).Warning("Failed to parse URL, skipping provider")
} }
bundles[idx] = &providerBundle{ bundles[idx] = &providerBundle{
s: s, s: s,
Host: externalHost.Host, Host: externalHost.Host,
log: log.WithField("logger", "authentik.outpost.proxy-bundle").WithField("provider", provider.Name), log: log.WithField("logger", "authentik.outpost.proxy-bundle").WithField("provider", provider.Name),
endSessionUrl: provider.OidcConfiguration.EndSessionEndpoint,
} }
bundles[idx].Build(provider) bundles[idx].Build(provider)
} }

View File

@ -25,6 +25,8 @@ type providerBundle struct {
proxy *OAuthProxy proxy *OAuthProxy
Host string Host string
endSessionUrl string
cert *tls.Certificate cert *tls.Certificate
log *log.Entry log *log.Entry
@ -155,6 +157,7 @@ func (pb *providerBundle) Build(provider api.ProxyOutpostConfig) {
oauthproxy.BasicAuthPasswordAttribute = *provider.BasicAuthPasswordAttribute oauthproxy.BasicAuthPasswordAttribute = *provider.BasicAuthPasswordAttribute
} }
oauthproxy.endSessionEndpoint = pb.endSessionUrl
oauthproxy.ExternalHost = pb.Host oauthproxy.ExternalHost = pb.Host
pb.proxy = oauthproxy pb.proxy = oauthproxy

View File

@ -65,31 +65,33 @@ type OAuthProxy struct {
AuthOnlyPath string AuthOnlyPath string
UserInfoPath string UserInfoPath string
endSessionEndpoint string
mode api.ProxyMode mode api.ProxyMode
redirectURL *url.URL // the url to receive requests at
whitelistDomains []string
provider providers.Provider
sessionStore sessionsapi.SessionStore
ProxyPrefix string
serveMux http.Handler
SetXAuthRequest bool
SetBasicAuth bool
PassUserHeaders bool
BasicAuthUserAttribute string BasicAuthUserAttribute string
BasicAuthPasswordAttribute string BasicAuthPasswordAttribute string
ExternalHost string ExternalHost string
PassAccessToken bool
SetAuthorization bool redirectURL *url.URL // the url to receive requests at
PassAuthorization bool whitelistDomains []string
PreferEmailToUser bool provider providers.Provider
skipAuthRegex []string sessionStore sessionsapi.SessionStore
skipAuthPreflight bool ProxyPrefix string
skipAuthStripHeaders bool serveMux http.Handler
mainJwtBearerVerifier *oidc.IDTokenVerifier SetXAuthRequest bool
extraJwtBearerVerifiers []*oidc.IDTokenVerifier SetBasicAuth bool
compiledRegex []*regexp.Regexp PassUserHeaders bool
templates *template.Template PassAccessToken bool
realClientIPParser ipapi.RealClientIPParser SetAuthorization bool
PassAuthorization bool
PreferEmailToUser bool
skipAuthRegex []string
skipAuthPreflight bool
skipAuthStripHeaders bool
mainJwtBearerVerifier *oidc.IDTokenVerifier
extraJwtBearerVerifiers []*oidc.IDTokenVerifier
compiledRegex []*regexp.Regexp
templates *template.Template
realClientIPParser ipapi.RealClientIPParser
sessionChain alice.Chain sessionChain alice.Chain
@ -285,19 +287,13 @@ func (p *OAuthProxy) UserInfo(rw http.ResponseWriter, req *http.Request) {
// SignOut sends a response to clear the authentication cookie // SignOut sends a response to clear the authentication cookie
func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) { func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) {
redirect, err := p.GetRedirect(req) err := p.ClearSessionCookie(rw, req)
if err != nil {
p.logger.Errorf("Error obtaining redirect: %v", err)
p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
return
}
err = p.ClearSessionCookie(rw, req)
if err != nil { if err != nil {
p.logger.Errorf("Error clearing session cookie: %v", err) p.logger.Errorf("Error clearing session cookie: %v", err)
p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error()) p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
return return
} }
http.Redirect(rw, req, redirect, http.StatusFound) http.Redirect(rw, req, p.endSessionEndpoint, http.StatusFound)
} }
// AuthenticateOnly checks whether the user is currently logged in // AuthenticateOnly checks whether the user is currently logged in

View File

@ -119,6 +119,13 @@ class TestProviderProxy(SeleniumTestCase):
self.assertIn("X-Forwarded-Preferred-Username: akadmin", full_body_text) self.assertIn("X-Forwarded-Preferred-Username: akadmin", full_body_text)
self.assertIn("X-Foo: bar", full_body_text) self.assertIn("X-Foo: bar", full_body_text)
self.driver.get("http://localhost:4180/akprox/sign_out")
sleep(2)
full_body_text = self.driver.find_element(
By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl"
).text
self.assertIn("You've logged out of proxy.", full_body_text)
@skipUnless(platform.startswith("linux"), "requires local docker") @skipUnless(platform.startswith("linux"), "requires local docker")
class TestProviderProxyConnect(ChannelsLiveServerTestCase): class TestProviderProxyConnect(ChannelsLiveServerTestCase):