|
1 | 1 | /* |
2 | 2 | * JavaScript functions for providing OpenID Connect with NGINX Plus |
3 | | - * |
| 3 | + * |
4 | 4 | * Copyright (C) 2020 Nginx, Inc. |
5 | 5 | */ |
6 | 6 | var newSession = false; // Used by oidcAuth() and validateIdToken() |
@@ -51,7 +51,7 @@ function auth(r, afterSyncCheck) { |
51 | 51 | r.return(302, r.variables.oidc_authz_endpoint + getAuthZArgs(r)); |
52 | 52 | return; |
53 | 53 | } |
54 | | - |
| 54 | + |
55 | 55 | // Pass the refresh token to the /_refresh location so that it can be |
56 | 56 | // proxied to the IdP in exchange for a new id_token |
57 | 57 | r.subrequest("/_refresh", "token=" + r.variables.refresh_token, |
@@ -266,10 +266,43 @@ function validateIdToken(r) { |
266 | 266 |
|
267 | 267 | function logout(r) { |
268 | 268 | r.log("OIDC logout for " + r.variables.cookie_auth_token); |
269 | | - r.variables.session_jwt = "-"; |
270 | | - r.variables.access_token = "-"; |
271 | | - r.variables.refresh_token = "-"; |
272 | | - r.return(302, r.variables.oidc_logout_redirect); |
| 269 | + |
| 270 | + // Determine if oidc_logout_redirect is a full URL or a relative path |
| 271 | + function getLogoutRedirectUrl(base, redirect) { |
| 272 | + return redirect.match(/^(http|https):\/\//) ? redirect : base + redirect; |
| 273 | + } |
| 274 | + |
| 275 | + var logoutRedirectUrl = getLogoutRedirectUrl(r.variables.redirect_base, r.variables.oidc_logout_redirect); |
| 276 | + |
| 277 | + // Helper function to perform the final logout steps |
| 278 | + function performLogout(redirectUrl) { |
| 279 | + r.variables.session_jwt = '-'; |
| 280 | + r.variables.access_token = '-'; |
| 281 | + r.variables.refresh_token = '-'; |
| 282 | + r.return(302, redirectUrl); |
| 283 | + } |
| 284 | + |
| 285 | + // Check if OIDC end session endpoint is available |
| 286 | + if (r.variables.oidc_end_session_endpoint) { |
| 287 | + |
| 288 | + if (!r.variables.session_jwt || r.variables.session_jwt === '-') { |
| 289 | + if (r.variables.refresh_token && r.variables.refresh_token !== '-') { |
| 290 | + // Renew ID token if only refresh token is available |
| 291 | + auth(r, 0); |
| 292 | + } else { |
| 293 | + performLogout(logoutRedirectUrl); |
| 294 | + return; |
| 295 | + } |
| 296 | + } |
| 297 | + |
| 298 | + // Construct logout arguments for RP-initiated logout |
| 299 | + var logoutArgs = "?post_logout_redirect_uri=" + encodeURIComponent(logoutRedirectUrl) + |
| 300 | + "&id_token_hint=" + encodeURIComponent(r.variables.session_jwt); |
| 301 | + performLogout(r.variables.oidc_end_session_endpoint + logoutArgs); |
| 302 | + } else { |
| 303 | + // Fallback to traditional logout approach |
| 304 | + performLogout(logoutRedirectUrl); |
| 305 | + } |
273 | 306 | } |
274 | 307 |
|
275 | 308 | function getAuthZArgs(r) { |
@@ -311,5 +344,5 @@ function idpClientAuth(r) { |
311 | 344 | return "code=" + r.variables.arg_code + "&code_verifier=" + r.variables.pkce_code_verifier; |
312 | 345 | } else { |
313 | 346 | return "code=" + r.variables.arg_code + "&client_secret=" + r.variables.oidc_client_secret; |
314 | | - } |
| 347 | + } |
315 | 348 | } |
0 commit comments