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.
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');