From 82f451e932d70dbd4bfbe903fd8a913df2c444c8 Mon Sep 17 00:00:00 2001 From: Kayathiri Mahendrakumaran Date: Fri, 6 Sep 2024 13:09:49 +0530 Subject: [PATCH] Fix to retrun oidc claims based on the requested scopes --- .../DefaultOIDCClaimsCallbackHandler.java | 23 +++++++++++++++++- .../identity/openidconnect/OIDCClaimUtil.java | 24 +++++++++++++++++++ .../DefaultOIDCClaimsCallbackHandlerTest.java | 12 +++++++--- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/DefaultOIDCClaimsCallbackHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/DefaultOIDCClaimsCallbackHandler.java index 6a722435e4..28ecc6a82e 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/DefaultOIDCClaimsCallbackHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/DefaultOIDCClaimsCallbackHandler.java @@ -170,7 +170,7 @@ private Map getUserClaimsInOIDCDialect(OAuthTokenReqMessageConte userClaimsInOIDCDialect = retrieveClaimsForLocalUser(requestMsgCtx); } else { // Get claim map from the cached attributes - userClaimsInOIDCDialect = getOIDCClaimMapFromUserAttributes(userAttributes); + userClaimsInOIDCDialect = getOIDCClaimsFromUserAttributes(userAttributes, requestMsgCtx); } Object hasNonOIDCClaimsProperty = requestMsgCtx.getProperty(OIDCConstants.HAS_NON_OIDC_CLAIMS); @@ -594,6 +594,27 @@ private Map getOIDCClaimMapFromUserAttributes(Map getOIDCClaimsFromUserAttributes(Map userAttributes, + OAuthTokenReqMessageContext requestMsgCtx) + throws IdentityOAuth2Exception { + + String spTenantDomain = getServiceProviderTenantDomain(requestMsgCtx); + Map claims = new HashMap<>(); + if (isNotEmpty(userAttributes)) { + for (Map.Entry entry : userAttributes.entrySet()) { + claims.put(entry.getKey().getRemoteClaim().getClaimUri(), entry.getValue().toString()); + } + } + return OIDCClaimUtil.getMergedUserClaimsInOIDCDialect(spTenantDomain, claims); + } + private Map getUserClaimsInOIDCDialect(String spTenantDomain, String clientId, AuthenticatedUser authenticatedUser) throws IdentityApplicationManagementException, IdentityException, UserStoreException, diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/OIDCClaimUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/OIDCClaimUtil.java index 7c872fa8a7..5cee4478ea 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/OIDCClaimUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/OIDCClaimUtil.java @@ -255,6 +255,30 @@ public static Map filterUserClaimsBasedOnConsent(Map getMergedUserClaimsInOIDCDialect(String spTenantDomain, + Map claims) + throws IdentityOAuth2Exception { + + Map oidcClaims = new HashMap<>(); + try { + oidcClaims = OIDCClaimUtil.getUserClaimsInOIDCDialect(spTenantDomain, claims); + // Merge the initial claims into oidcClaims, while prioritizing the initial claims map. + oidcClaims.putAll(claims); + return oidcClaims; + } catch (ClaimMetadataException e) { + throw new IdentityOAuth2Exception("Error occurred while mapping claims for user: " + + " from userstore.", e); + } + } + public static Map filterUserClaimsBasedOnConsent(Map userClaims, AuthenticatedUser authenticatedUser, String clientId, diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/DefaultOIDCClaimsCallbackHandlerTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/DefaultOIDCClaimsCallbackHandlerTest.java index 778d7e94dc..4e21c36bbe 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/DefaultOIDCClaimsCallbackHandlerTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/DefaultOIDCClaimsCallbackHandlerTest.java @@ -484,13 +484,15 @@ public void testHandleCustomClaimsWithoutClaimsInUserAttributes() throws Excepti MockedStatic jdbcPersistenceManager = mockStatic(JDBCPersistenceManager.class); MockedStatic oAuthServerConfiguration = mockStatic( - OAuthServerConfiguration.class)) { + OAuthServerConfiguration.class); + MockedStatic claimMetadataHandler = mockStatic(ClaimMetadataHandler.class);) { // Create a token request with User Attributes. JWTClaimsSet.Builder jwtClaimsSetBuilder = new JWTClaimsSet.Builder(); Map userAttributes = new HashMap<>(); userAttributes.put(SAML2BearerGrantHandlerTest.buildClaimMapping(COUNTRY), TestConstants.CLAIM_VALUE1); userAttributes.put(SAML2BearerGrantHandlerTest.buildClaimMapping(EMAIL), TestConstants.CLAIM_VALUE2); OAuthTokenReqMessageContext requestMsgCtx = getTokenReqMessageContextForFederatedUser(userAttributes); + getUserClaimsMap(claimMetadataHandler); // Mock to return all the scopes when the consent is asked for. UserRealm userRealm = getUserRealmWithUserClaims(USER_CLAIMS_MAP); @@ -516,7 +518,8 @@ public void testHandleCustomClaimsWithoutClaimsInRefreshFlow() throws Exception MockedStatic oAuthServerConfiguration = mockStatic( OAuthServerConfiguration.class); MockedStatic authorizationGrantCache = - mockStatic(AuthorizationGrantCache.class);) { + mockStatic(AuthorizationGrantCache.class); + MockedStatic claimMetadataHandler = mockStatic(ClaimMetadataHandler.class);) { JWTClaimsSet.Builder jwtClaimsSetBuilder = new JWTClaimsSet.Builder(); OAuthTokenReqMessageContext requestMsgCtx = getTokenReqMessageContextForFederatedUser(null); // Add the relevant oidc claims to scope resource. @@ -535,6 +538,7 @@ public void testHandleCustomClaimsWithoutClaimsInRefreshFlow() throws Exception new AuthorizationGrantCacheEntry(userAttributes); authorizationGrantCacheEntry.setSubjectClaim(requestMsgCtx.getAuthorizedUser().getUserName()); mockAuthorizationGrantCache(authorizationGrantCacheEntry, authorizationGrantCache); + getUserClaimsMap(claimMetadataHandler); RefreshTokenValidationDataDO refreshTokenValidationDataDO = Mockito.mock(RefreshTokenValidationDataDO.class); @@ -1169,7 +1173,8 @@ public void testHandleClaimsForOAuthTokenReqMessageContextWithAuthorizationCode( MockedStatic oAuthServerConfiguration = mockStatic( OAuthServerConfiguration.class); MockedStatic authorizationGrantCache = - mockStatic(AuthorizationGrantCache.class);) { + mockStatic(AuthorizationGrantCache.class); + MockedStatic claimMetadataHandler = mockStatic(ClaimMetadataHandler.class);) { JWTClaimsSet.Builder jwtClaimsSetBuilder = new JWTClaimsSet.Builder(); Map userAttributes = new HashMap<>(); userAttributes.put(SAML2BearerGrantHandlerTest.buildClaimMapping(COUNTRY), TestConstants.CLAIM_VALUE1); @@ -1179,6 +1184,7 @@ public void testHandleClaimsForOAuthTokenReqMessageContextWithAuthorizationCode( AuthorizationGrantCacheEntry authorizationGrantCacheEntry = mock(AuthorizationGrantCacheEntry.class); mockAuthorizationGrantCache(authorizationGrantCacheEntry, authorizationGrantCache); + getUserClaimsMap(claimMetadataHandler); UserRealm userRealm = getUserRealmWithUserClaims(USER_CLAIMS_MAP); mockUserRealm(requestMsgCtx.getAuthorizedUser().toString(), userRealm, identityTenantUtil);