Răsfoiți Sursa

fix(auth): keycloak authentication post logout redirect for Keycloak 18+ (#5878)

Jason Minard 1 an în urmă
părinte
comite
491d63ceee

+ 1 - 1
server/models/users.js

@@ -866,7 +866,7 @@ module.exports = class User extends Model {
     }
     const usr = await WIKI.models.users.query().findById(context.req.user.id).select('providerKey')
     const provider = _.find(WIKI.auth.strategies, ['key', usr.providerKey])
-    return provider.logout ? provider.logout(provider.config) : '/'
+    return provider.logout ? provider.logout(provider.config, context) : '/'
   }
 
   static async getGuestUser () {

+ 15 - 3
server/modules/authentication/keycloak/authentication.js

@@ -21,7 +21,7 @@ module.exports = {
         clientSecret: conf.clientSecret,
         callbackURL: conf.callbackURL,
         passReqToCallback: true
-      }, async (req, accessToken, refreshToken, profile, cb) => {
+      }, async (req, accessToken, refreshToken, results, profile, cb) => {
         let displayName = profile.username
         if (_.isString(profile.fullName) && profile.fullName.length > 0) {
           displayName = profile.fullName
@@ -36,6 +36,7 @@ module.exports = {
               picture: ''
             }
           })
+          req.session.keycloak_id_token = results.id_token
           cb(null, user)
         } catch (err) {
           cb(err, null)
@@ -43,11 +44,22 @@ module.exports = {
       })
     )
   },
-  logout (conf) {
+  logout (conf, context) {
     if (!conf.logoutUpstream) {
       return '/'
     } else if (conf.logoutURL && conf.logoutURL.length > 5) {
-      return `${conf.logoutURL}?redirect_uri=${encodeURIComponent(WIKI.config.host)}`
+      const idToken = context.req.session.keycloak_id_token
+      const redirURL = encodeURIComponent(WIKI.config.host)
+      if (conf.logoutUpstreamRedirectLegacy) {
+        // keycloak < 18
+        return `${conf.logoutURL}?redirect_uri=${redirURL}`
+      } else if (idToken) {
+        // keycloak 18+
+        return `${conf.logoutURL}?post_logout_redirect_uri=${redirURL}&id_token_hint=${idToken}`
+      } else {
+        // fall back to no redirect if keycloak_id_token isn't available
+        return conf.logoutURL
+      }
     } else {
       WIKI.logger.warn('Keycloak logout URL is not configured!')
       return '/'

+ 5 - 0
server/modules/authentication/keycloak/definition.yml

@@ -57,4 +57,9 @@ props:
     title: Logout Endpoint URL
     hint: e.g. https://KEYCLOAK-HOST/auth/realms/YOUR-REALM/protocol/openid-connect/logout
     order: 9
+  logoutUpstreamRedirectLegacy:
+    type: Boolean
+    title: Legacy Logout Redirect
+    hint: Pass the legacy 'redirect_uri' parameter to the logout endpoint. Leave disabled for Keycloak 18 and above.
+    order: 10