mirror of
https://github.com/photoprism/photoprism.git
synced 2026-07-17 16:49:04 +00:00
Sign-out of an OIDC session redirects the browser to the provider's discovered end_session_endpoint (id_token_hint + absolute post_logout_redirect_uri) when PHOTOPRISM_OIDC_LOGOUT is enabled, so the provider SSO session ends and the next login re-prompts. Opt-in (default off); local/LDAP logout and providers without an end-session endpoint fall back to local logout. Adds the shared CE /api/v1/oauth/logout route and OAuthLogoutHandler hook plus the Portal OP end_session_endpoint advertised in the Portal discovery document, for Portal builds to serve via the override hook.
This commit is contained in:
parent
3f096a592b
commit
50976f427e
21 changed files with 576 additions and 10 deletions
|
|
@ -50,6 +50,7 @@ func registerRoutes(router *gin.Engine, conf *config.Config) {
|
|||
api.OAuthUserinfo(APIv1)
|
||||
api.OAuthToken(APIv1)
|
||||
api.OAuthRevoke(APIv1)
|
||||
api.OAuthLogout(APIv1)
|
||||
|
||||
// OIDC Client Endpoints.
|
||||
api.OIDCLogin(APIv1)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ func NewPortalOpenIDConfiguration(conf *config.Config) *OpenIDConfiguration {
|
|||
AuthorizationEndpoint: issuer + config.ApiUri + "/oauth/authorize",
|
||||
TokenEndpoint: issuer + config.ApiUri + "/oauth/token",
|
||||
UserinfoEndpoint: issuer + config.ApiUri + "/oauth/userinfo",
|
||||
EndSessionEndpoint: issuer + config.ApiUri + "/oauth/logout",
|
||||
JwksUri: issuer + "/.well-known/jwks.json",
|
||||
ResponseTypesSupported: PortalOIDCResponseTypes,
|
||||
GrantTypesSupported: PortalOIDCGrantTypes,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ func TestPortalOpenIDConfiguration(t *testing.T) {
|
|||
assert.Equal(t, "http://localhost:2342/api/v1/oauth/authorize", result.AuthorizationEndpoint)
|
||||
assert.Equal(t, "http://localhost:2342/api/v1/oauth/token", result.TokenEndpoint)
|
||||
assert.Equal(t, "http://localhost:2342/api/v1/oauth/userinfo", result.UserinfoEndpoint)
|
||||
assert.Equal(t, "http://localhost:2342/api/v1/oauth/logout", result.EndSessionEndpoint)
|
||||
assert.Equal(t, "http://localhost:2342/.well-known/jwks.json", result.JwksUri)
|
||||
})
|
||||
t.Run("Capabilities", func(t *testing.T) {
|
||||
|
|
@ -46,13 +47,14 @@ func TestPortalOpenIDConfiguration(t *testing.T) {
|
|||
c.Options().SiteUrl = "http://foo:2342/foo/"
|
||||
result := NewPortalOpenIDConfiguration(c)
|
||||
|
||||
for _, u := range []string{result.Issuer, result.AuthorizationEndpoint, result.TokenEndpoint, result.UserinfoEndpoint, result.JwksUri} {
|
||||
for _, u := range []string{result.Issuer, result.AuthorizationEndpoint, result.TokenEndpoint, result.UserinfoEndpoint, result.EndSessionEndpoint, result.JwksUri} {
|
||||
assert.Equal(t, 1, strings.Count(u, "/foo/"), "base path must appear exactly once in %s", u)
|
||||
assert.NotContains(t, u, "/foo/foo/", "base path must not be doubled in %s", u)
|
||||
}
|
||||
assert.Equal(t, "http://foo:2342/foo/api/v1/oauth/authorize", result.AuthorizationEndpoint)
|
||||
assert.Equal(t, "http://foo:2342/foo/api/v1/oauth/token", result.TokenEndpoint)
|
||||
assert.Equal(t, "http://foo:2342/foo/api/v1/oauth/userinfo", result.UserinfoEndpoint)
|
||||
assert.Equal(t, "http://foo:2342/foo/api/v1/oauth/logout", result.EndSessionEndpoint)
|
||||
assert.Equal(t, "http://foo:2342/foo/.well-known/jwks.json", result.JwksUri)
|
||||
})
|
||||
t.Run("IssuerWithTrailingSlashIsNormalized", func(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue