diff --git a/components/org.wso2.carbon.identity.application.authenticator.oidc/src/main/java/org/wso2/carbon/identity/application/authenticator/oidc/logout/idpinit/processor/FederatedIdpInitLogoutProcessor.java b/components/org.wso2.carbon.identity.application.authenticator.oidc/src/main/java/org/wso2/carbon/identity/application/authenticator/oidc/logout/idpinit/processor/FederatedIdpInitLogoutProcessor.java index 6c9e9cf1..abf978fb 100644 --- a/components/org.wso2.carbon.identity.application.authenticator.oidc/src/main/java/org/wso2/carbon/identity/application/authenticator/oidc/logout/idpinit/processor/FederatedIdpInitLogoutProcessor.java +++ b/components/org.wso2.carbon.identity.application.authenticator.oidc/src/main/java/org/wso2/carbon/identity/application/authenticator/oidc/logout/idpinit/processor/FederatedIdpInitLogoutProcessor.java @@ -70,6 +70,7 @@ import static org.wso2.carbon.identity.application.authenticator.oidc.OIDCAuthenticatorConstants.BackchannelLogout.DEFAULT_IAT_VALIDITY_PERIOD; import static org.wso2.carbon.identity.application.authenticator.oidc.OIDCAuthenticatorConstants.OIDC_BACKCHANNEL_LOGOUT_ENDPOINT_URL_PATTERN; import static org.wso2.carbon.identity.application.authenticator.oidc.util.OIDCErrorConstants.ErrorMessages; +import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.RESIDENT_IDP_RESERVED_NAME; /** * Processes the OIDC federated idp initiated logout requests. @@ -175,22 +176,26 @@ protected LogoutResponse.LogoutResponseBuilder logoutUsingSid(String sid) if (log.isDebugEnabled()) { log.debug(String.format("Trying federated IdP initiated logout using sid: %s.", sid)); } - FederatedUserSession federatedUserSession = getFederatedUserSessionFromSid(sid); + List federatedUserSessionList = getFederatedUserSessionsFromSid(sid); String sessionId = null; - if (federatedUserSession != null) { - sessionId = federatedUserSession.getSessionId(); - } - if (StringUtils.isBlank(sessionId)) { - return new LogoutResponse.LogoutResponseBuilder(HttpServletResponse.SC_OK, StringUtils.EMPTY); - } + for (FederatedUserSession federatedUserSession: federatedUserSessionList) { + if (federatedUserSession != null) { + sessionId = federatedUserSession.getSessionId(); + } + if (StringUtils.isBlank(sessionId)) { + return new LogoutResponse.LogoutResponseBuilder(HttpServletResponse.SC_OK, StringUtils.EMPTY); + } - ServerSessionManagementService serverSessionManagementService = - OpenIDConnectAuthenticatorDataHolder.getInstance().getServerSessionManagementService(); - serverSessionManagementService.removeSession(sessionId); - if (log.isDebugEnabled()) { - log.debug("Session terminated for session Id: " + sessionId); + ServerSessionManagementService serverSessionManagementService = + OpenIDConnectAuthenticatorDataHolder.getInstance().getServerSessionManagementService(); + serverSessionManagementService.removeSession(sessionId); + removeFederatedIDPSessionMapping(sessionId); + if (log.isDebugEnabled()) { + log.debug("Session terminated for session Id: " + sessionId); + } } + return new LogoutResponse.LogoutResponseBuilder(HttpServletResponse.SC_OK, OIDCAuthenticatorConstants.BackchannelLogout.LOGOUT_SUCCESS); } @@ -220,6 +225,24 @@ protected FederatedUserSession getFederatedUserSessionFromSid(String sid) throws } } + protected List getFederatedUserSessionsFromSid(String sid) throws LogoutServerException { + + try { + UserSessionDAO userSessionDAO = new UserSessionDAOImpl(); + List federatedUserSession = userSessionDAO.getFederatedAuthSessionsDetails(sid); + if (federatedUserSession == null) { + if (log.isDebugEnabled()) { + log.debug(String.format("No session information found for the sid: %s. ", sid) + "Probably the " + + "session was cleared by another mechanism."); + } + return null; + } + return federatedUserSession; + } catch (SessionManagementServerException e) { + throw handleLogoutServerException(ErrorMessages.RETRIEVING_SESSION_ID_MAPPING_FAILED, e, sid); + } + } + /** * Terminate all the sessions of the user related sub claim. * @@ -346,6 +369,10 @@ protected void validateIssuerClaim(JWTClaimsSet claimsSet) throws LogoutClientEx */ protected void validateAudience(List aud, IdentityProvider idp) throws LogoutClientException { + // Validate audience is skipped for the resident IDP. + if (RESIDENT_IDP_RESERVED_NAME.equals(idp.getIdentityProviderName())) { + return; + } String clientId = null; // Get the client id from the authenticator config. for (Property property : idp.getDefaultAuthenticatorConfig().getProperties()) { @@ -691,4 +718,13 @@ private IdentityProvider getResidentIDPForIssuer(String tenantDomain, String jwt } return jwtIssuer.equals(issuer) ? residentIdentityProvider : null; } + + private void removeFederatedIDPSessionMapping(String sessionID) throws LogoutServerException { + + try { + UserSessionStore.getInstance().removeFederatedAuthSessionInfo(sessionID); + } catch (UserSessionException e) { + throw new LogoutServerException("Exception occurred while removing federated IDP session mapping."); + } + } } diff --git a/components/org.wso2.carbon.identity.application.authenticator.oidc/src/test/java/org/wso2/carbon/identity/application/authenticator/oidc/logout/idpinit/processor/FederatedIdpInitLogoutProcessorTest.java b/components/org.wso2.carbon.identity.application.authenticator.oidc/src/test/java/org/wso2/carbon/identity/application/authenticator/oidc/logout/idpinit/processor/FederatedIdpInitLogoutProcessorTest.java index 9237f859..b2fcc5a4 100644 --- a/components/org.wso2.carbon.identity.application.authenticator.oidc/src/test/java/org/wso2/carbon/identity/application/authenticator/oidc/logout/idpinit/processor/FederatedIdpInitLogoutProcessorTest.java +++ b/components/org.wso2.carbon.identity.application.authenticator.oidc/src/test/java/org/wso2/carbon/identity/application/authenticator/oidc/logout/idpinit/processor/FederatedIdpInitLogoutProcessorTest.java @@ -72,6 +72,7 @@ import javax.sql.DataSource; import javax.xml.stream.XMLInputFactory; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.powermock.api.mockito.PowerMockito.mockStatic; @@ -485,7 +486,7 @@ public void testOidcFederatedLogout() throws Exception { DataSource dataSource = mock(DataSource.class); mockStatic(IdentityDatabaseUtil.class); when(IdentityDatabaseUtil.getDataSource()).thenReturn(dataSource); - when(IdentityDatabaseUtil.getDBConnection(false)).thenReturn(getConnection(DB_NAME)); + when(IdentityDatabaseUtil.getDBConnection(anyBoolean())).thenReturn(getConnection(DB_NAME)); when(dataSource.getConnection()).thenReturn(getConnection(DB_NAME)); // Mock the server session management service. diff --git a/pom.xml b/pom.xml index 6ba36973..6ea951f7 100644 --- a/pom.xml +++ b/pom.xml @@ -304,7 +304,7 @@ ${project.version} - 7.0.93 + 7.1.39 1.0.0.wso2v3 2.4.7 3.0.0.wso2v4