From 96e0dc15a37de04ba7c1debe954ba76a3b5b3087 Mon Sep 17 00:00:00 2001 From: Tom T <22985628+thatguyfig@users.noreply.github.com> Date: Sat, 16 May 2026 11:41:11 +0100 Subject: [PATCH] feat(oauth): Support AWS Cognito OAuth2 provider (#37607) Using the standard OpenID Connect OAuth2 provider type doesn't work well for AWS Cognito. Most of the functionality works absolutely fine, however the query parameter `post_logout_redirect_uri` is not understood by Cognito and results in a bad experience when logging out. To combat this i've added a new `AWS Cognito` provider which is almost identical to the `Open ID Connect` type except it overrides the query parameter to `logout_uri` which is what Cognito expects. image This then results in a nice experience logging out with no errors seen - even though the logout does succeed. Why AWS thought they would deviate from the OAuth spec in this particular area is beyond me... --------- Co-authored-by: Tom Thornton Co-authored-by: wxiaoguang Co-authored-by: Nicolas --- routers/web/auth/oauth.go | 10 ++++++++- .../auth/source/oauth2/providers_custom.go | 21 +++++++++++++++++++ web_src/js/features/admin/common.ts | 1 + 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index d42ec88ac6..867106d352 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -561,7 +561,15 @@ func buildOIDCEndSessionURL(ctx *context.Context, doer *user_model.User) string // https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout params := endSessionURL.Query() params.Set("client_id", oauth2Cfg.ClientID) - params.Set("post_logout_redirect_uri", httplib.GuessCurrentAppURL(ctx)) + + // AWS Cognito uses "logout_uri" instead of the standard "post_logout_redirect_uri" + redirectURI := httplib.GuessCurrentAppURL(ctx) + if oauth2Cfg.Provider == oauth2.ProviderNameAwsCognito { + params.Set("logout_uri", redirectURI) + } else { + params.Set("post_logout_redirect_uri", redirectURI) + } + endSessionURL.RawQuery = params.Encode() return endSessionURL.String() } diff --git a/services/auth/source/oauth2/providers_custom.go b/services/auth/source/oauth2/providers_custom.go index 65cf538ad7..6a4098dda6 100644 --- a/services/auth/source/oauth2/providers_custom.go +++ b/services/auth/source/oauth2/providers_custom.go @@ -120,4 +120,25 @@ func init() { }), nil }, )) + + RegisterGothProvider(&AwsCognitoProvider{}) } + +const ProviderNameAwsCognito = "aws-cognito" + +// AwsCognitoProvider is a GothProvider for AWS Cognito (based on OpenID Connect) +type AwsCognitoProvider struct { + OpenIDProvider +} + +// Name provides the technical name for this provider +func (c *AwsCognitoProvider) Name() string { + return ProviderNameAwsCognito +} + +// DisplayName returns the friendly name for this provider +func (c *AwsCognitoProvider) DisplayName() string { + return "AWS Cognito" +} + +var _ GothProvider = &AwsCognitoProvider{} diff --git a/web_src/js/features/admin/common.ts b/web_src/js/features/admin/common.ts index f0c0f5bee6..5753aad2b2 100644 --- a/web_src/js/features/admin/common.ts +++ b/web_src/js/features/admin/common.ts @@ -86,6 +86,7 @@ function initAdminAuthentication() { const provider = document.querySelector('#oauth2_provider')!.value; switch (provider) { case 'openidConnect': + case 'aws-cognito': document.querySelector('.open_id_connect_auto_discovery_url input')!.setAttribute('required', 'required'); showElem('.open_id_connect_auto_discovery_url'); showElem('.open_id_connect_external_id_claim');