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:
		| @ -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) | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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): | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer