From 9d4d84a617999ba120a0b42376aa890e96f7c933 Mon Sep 17 00:00:00 2001 From: YuriyZ Date: Tue, 4 Oct 2022 13:16:06 +0300 Subject: [PATCH] fix(jans-auth-server): "login:prompt" property passed in request object JWT breaks authentication #2493 (#2537) docs: no docs https://github.com/JanssenProject/jans/issues/2493 --- .../main/java/io/jans/as/model/util/Util.java | 6 +++- .../ws/rs/AuthorizeRestWebServiceImpl.java | 33 +++++++++++++++---- .../server/authorize/ws/rs/AuthzRequest.java | 9 +++++ .../authorize/ws/rs/AuthzRequestService.java | 1 + 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/jans-auth-server/model/src/main/java/io/jans/as/model/util/Util.java b/jans-auth-server/model/src/main/java/io/jans/as/model/util/Util.java index 336a2b10bf4..3b45fe8ecd8 100644 --- a/jans-auth-server/model/src/main/java/io/jans/as/model/util/Util.java +++ b/jans-auth-server/model/src/main/java/io/jans/as/model/util/Util.java @@ -292,10 +292,14 @@ public static boolean isNullOrEmpty(String string) { } public static int parseIntSilently(String intString) { + return parseIntSilently(intString, -1); + } + + public static int parseIntSilently(String intString, int defaultValue) { try { return Integer.parseInt(intString); } catch (Exception e) { - return -1; + return defaultValue; } } diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthorizeRestWebServiceImpl.java b/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthorizeRestWebServiceImpl.java index 07e27c03a70..91353d03274 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthorizeRestWebServiceImpl.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthorizeRestWebServiceImpl.java @@ -502,6 +502,7 @@ private ResponseBuilder authorize(AuthzRequest authzRequest) throws AcrChangedEx ResponseBuilder builder = RedirectUtil.getRedirectResponseBuilder(authzRequest.getRedirectUriResponse().getRedirectUri(), authzRequest.getHttpRequest()); addCustomHeaders(builder, authzRequest); + updateSessionRpRedirect(sessionUser); runCiba(authzRequest.getAuthReqId(), client, authzRequest.getHttpRequest(), authzRequest.getHttpResponse()); processDeviceAuthorization(deviceAuthzUserCode, user); @@ -572,15 +573,18 @@ private void checkPromptConsent(AuthzRequest authzRequest, List prompts, private void checkPromptLogin(AuthzRequest authzRequest, List prompts) { if (prompts.contains(Prompt.LOGIN)) { + boolean sessionUnauthenticated = false; // workaround for #1030 - remove only authenticated session, for set up acr we set it unauthenticated and then drop in AuthorizeAction if (identity.getSessionId().getState() == SessionIdState.AUTHENTICATED) { - unauthenticateSession(authzRequest.getSessionId(), authzRequest.getHttpRequest()); + sessionUnauthenticated = unauthenticateSession(authzRequest.getSessionId(), authzRequest.getHttpRequest(), authzRequest.isPromptFromJwt()); } authzRequest.setSessionId(null); prompts.remove(Prompt.LOGIN); - throw new WebApplicationException(redirectToAuthorizationPage(authzRequest, prompts)); + if (sessionUnauthenticated) { + throw new WebApplicationException(redirectToAuthorizationPage(authzRequest, prompts)); + } } } @@ -731,7 +735,7 @@ private Pair ifUserIsNull(AuthzRequest authzRequest) throws Sea } } else { if (prompts.contains(Prompt.LOGIN)) { - unauthenticateSession(authzRequest.getSessionId(), authzRequest.getHttpRequest()); + unauthenticateSession(authzRequest.getSessionId(), authzRequest.getHttpRequest(), authzRequest.isPromptFromJwt()); authzRequest.setSessionId(null); prompts.remove(Prompt.LOGIN); authzRequest.setPrompt(implode(prompts, " ")); @@ -906,17 +910,33 @@ private Response redirectTo(String pathToRedirect, AuthzRequest authzRequest, Li return builder.build(); } - private void unauthenticateSession(String sessionId, HttpServletRequest httpRequest) { - identity.logout(); + private void updateSessionRpRedirect(SessionId sessionUser) { + int rpRedirectCount = Util.parseIntSilently(sessionUser.getSessionAttributes().get("successful_rp_redirect_count"), 0); + rpRedirectCount++; + + sessionUser.getSessionAttributes().put("successful_rp_redirect_count", Integer.toString(rpRedirectCount)); + sessionIdService.updateSessionId(sessionUser); + } + + private boolean unauthenticateSession(String sessionId, HttpServletRequest httpRequest) { + return unauthenticateSession(sessionId, httpRequest, false); + } + private boolean unauthenticateSession(String sessionId, HttpServletRequest httpRequest, boolean isPromptFromJwt) { SessionId sessionUser = identity.getSessionId(); + if (isPromptFromJwt && sessionUser != null && !sessionUser.getSessionAttributes().containsKey("successful_rp_redirect_count")) { + return false; // skip unauthentication because there were no at least one successful rp redirect + } + if (sessionUser != null) { sessionUser.setUserDn(null); sessionUser.setUser(null); sessionUser.setAuthenticationTime(null); } + identity.logout(); + if (StringHelper.isEmpty(sessionId)) { sessionId = cookieService.getSessionIdFromCookie(httpRequest); } @@ -924,7 +944,7 @@ private void unauthenticateSession(String sessionId, HttpServletRequest httpRequ SessionId persistenceSessionId = sessionIdService.getSessionId(sessionId); if (persistenceSessionId == null) { log.error("Failed to load session from LDAP by session_id: '{}'", sessionId); - return; + return true; } persistenceSessionId.setState(SessionIdState.UNAUTHENTICATED); @@ -936,6 +956,7 @@ private void unauthenticateSession(String sessionId, HttpServletRequest httpRequ if (!result) { log.error("Failed to update session_id '{}'", sessionId); } + return result; } /** diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequest.java b/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequest.java index 9c1ee699645..1b6a8288ed1 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequest.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequest.java @@ -54,6 +54,15 @@ public class AuthzRequest { private RedirectUriResponse redirectUriResponse; private Client client; private OAuth2AuditLog auditLog; + private boolean promptFromJwt; + + public boolean isPromptFromJwt() { + return promptFromJwt; + } + + public void setPromptFromJwt(boolean promptFromJwt) { + this.promptFromJwt = promptFromJwt; + } public OAuth2AuditLog getAuditLog() { return auditLog; diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequestService.java b/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequestService.java index 82923d58616..4c11e80899b 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequestService.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequestService.java @@ -228,6 +228,7 @@ public void processRequestObject(AuthzRequest authzRequest, Client client, Set