mirror of
https://github.com/pomerium/pomerium.git
synced 2025-08-03 00:40:25 +02:00
core/authenticate: refactor idp sign out (#4582)
This commit is contained in:
parent
7211a8d819
commit
a0c92896ef
16 changed files with 318 additions and 93 deletions
|
@ -89,6 +89,7 @@ func (a *Authenticate) mountDashboard(r *mux.Router) {
|
|||
|
||||
// routes that don't need a session:
|
||||
sr.Path("/sign_out").Handler(httputil.HandlerFunc(a.SignOut))
|
||||
sr.Path("/signed_out").Handler(handlers.SignedOut(handlers.SignedOutData{})).Methods(http.MethodGet)
|
||||
|
||||
// routes that need a session:
|
||||
sr = sr.NewRoute().Subrouter()
|
||||
|
@ -266,33 +267,35 @@ func (a *Authenticate) signOutRedirect(w http.ResponseWriter, r *http.Request) e
|
|||
|
||||
rawIDToken := a.revokeSession(ctx, w, r)
|
||||
|
||||
redirectString := ""
|
||||
signOutURL, err := options.GetSignOutRedirectURL()
|
||||
authenticateURL, err := options.GetAuthenticateURL()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting authenticate url: %w", err)
|
||||
}
|
||||
|
||||
signOutRedirectURL, err := options.GetSignOutRedirectURL()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if signOutURL != nil {
|
||||
redirectString = signOutURL.String()
|
||||
}
|
||||
|
||||
var signOutURL string
|
||||
if uri := r.FormValue(urlutil.QueryRedirectURI); uri != "" {
|
||||
redirectString = uri
|
||||
signOutURL = uri
|
||||
} else if signOutRedirectURL != nil {
|
||||
signOutURL = signOutRedirectURL.String()
|
||||
} else {
|
||||
signOutURL = authenticateURL.ResolveReference(&url.URL{
|
||||
Path: "/.pomerium/signed_out",
|
||||
}).String()
|
||||
}
|
||||
|
||||
endSessionURL, err := authenticator.LogOut()
|
||||
if err == nil && redirectString != "" {
|
||||
params := endSessionURL.Query()
|
||||
params.Add("id_token_hint", rawIDToken)
|
||||
params.Add("post_logout_redirect_uri", redirectString)
|
||||
endSessionURL.RawQuery = params.Encode()
|
||||
redirectString = endSessionURL.String()
|
||||
} else if err != nil && !errors.Is(err, oidc.ErrSignoutNotImplemented) {
|
||||
log.Warn(r.Context()).Err(err).Msg("authenticate.SignOut: failed getting session")
|
||||
if idpSignOutURL, err := authenticator.GetSignOutURL(rawIDToken, signOutURL); err == nil {
|
||||
signOutURL = idpSignOutURL
|
||||
} else if !errors.Is(err, oidc.ErrSignoutNotImplemented) {
|
||||
log.Warn(r.Context()).Err(err).Msg("authenticate: failed to get sign out url for authenticator")
|
||||
}
|
||||
if redirectString != "" {
|
||||
httputil.Redirect(w, r, redirectString, http.StatusFound)
|
||||
return nil
|
||||
}
|
||||
return httputil.NewError(http.StatusOK, errors.New("user logged out"))
|
||||
|
||||
httputil.Redirect(w, r, signOutURL, http.StatusFound)
|
||||
return nil
|
||||
}
|
||||
|
||||
// reauthenticateOrFail starts the authenticate process by redirecting the
|
||||
|
|
|
@ -135,7 +135,7 @@ func TestAuthenticate_SignOut(t *testing.T) {
|
|||
"",
|
||||
"sig",
|
||||
"ts",
|
||||
identity.MockProvider{LogOutResponse: (*uriParseHelper("https://microsoft.com"))},
|
||||
identity.MockProvider{GetSignOutURLResponse: "https://microsoft.com"},
|
||||
&mstore.Store{Encrypted: true, Session: &sessions.State{}},
|
||||
http.StatusFound,
|
||||
"",
|
||||
|
@ -148,7 +148,7 @@ func TestAuthenticate_SignOut(t *testing.T) {
|
|||
"https://signout-redirect-url.example.com",
|
||||
"sig",
|
||||
"ts",
|
||||
identity.MockProvider{LogOutResponse: (*uriParseHelper("https://microsoft.com"))},
|
||||
identity.MockProvider{GetSignOutURLError: oidc.ErrSignoutNotImplemented},
|
||||
&mstore.Store{Encrypted: true, Session: &sessions.State{}},
|
||||
http.StatusFound,
|
||||
"",
|
||||
|
@ -161,7 +161,7 @@ func TestAuthenticate_SignOut(t *testing.T) {
|
|||
"",
|
||||
"sig",
|
||||
"ts",
|
||||
identity.MockProvider{RevokeError: errors.New("OH NO")},
|
||||
identity.MockProvider{GetSignOutURLError: oidc.ErrSignoutNotImplemented, RevokeError: errors.New("OH NO")},
|
||||
&mstore.Store{Encrypted: true, Session: &sessions.State{}},
|
||||
http.StatusFound,
|
||||
"",
|
||||
|
@ -174,7 +174,7 @@ func TestAuthenticate_SignOut(t *testing.T) {
|
|||
"",
|
||||
"sig",
|
||||
"ts",
|
||||
identity.MockProvider{RevokeError: errors.New("OH NO")},
|
||||
identity.MockProvider{GetSignOutURLError: oidc.ErrSignoutNotImplemented, RevokeError: errors.New("OH NO")},
|
||||
&mstore.Store{Encrypted: true, Session: &sessions.State{}},
|
||||
http.StatusFound,
|
||||
"",
|
||||
|
@ -187,24 +187,11 @@ func TestAuthenticate_SignOut(t *testing.T) {
|
|||
"",
|
||||
"sig",
|
||||
"ts",
|
||||
identity.MockProvider{LogOutError: oidc.ErrSignoutNotImplemented},
|
||||
identity.MockProvider{GetSignOutURLError: oidc.ErrSignoutNotImplemented},
|
||||
&mstore.Store{Encrypted: true, Session: &sessions.State{}},
|
||||
http.StatusFound,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"no redirect uri",
|
||||
http.MethodPost,
|
||||
nil,
|
||||
"",
|
||||
"",
|
||||
"sig",
|
||||
"ts",
|
||||
identity.MockProvider{LogOutResponse: (*uriParseHelper("https://microsoft.com"))},
|
||||
&mstore.Store{Encrypted: true, Session: &sessions.State{}},
|
||||
http.StatusOK,
|
||||
"{\"Status\":200}\n",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
|
@ -253,7 +240,7 @@ func TestAuthenticate_SignOut(t *testing.T) {
|
|||
}
|
||||
if tt.signoutRedirectURL != "" {
|
||||
loc := w.Header().Get("Location")
|
||||
assert.Contains(t, loc, url.QueryEscape(tt.signoutRedirectURL))
|
||||
assert.Contains(t, loc, tt.signoutRedirectURL)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue