diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.identity/src/main/java/com/wso2/openbanking/accelerator/identity/claims/OBDefaultOIDCClaimsCallbackHandler.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.identity/src/main/java/com/wso2/openbanking/accelerator/identity/claims/OBDefaultOIDCClaimsCallbackHandler.java index 52c8bdbb..509ac985 100644 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.identity/src/main/java/com/wso2/openbanking/accelerator/identity/claims/OBDefaultOIDCClaimsCallbackHandler.java +++ b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.identity/src/main/java/com/wso2/openbanking/accelerator/identity/claims/OBDefaultOIDCClaimsCallbackHandler.java @@ -31,6 +31,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext; import org.wso2.carbon.identity.oauth2.model.HttpRequestHeader; import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; import org.wso2.carbon.identity.openidconnect.DefaultOIDCClaimsCallbackHandler; @@ -91,6 +92,64 @@ public JWTClaimsSet handleCustomClaims(JWTClaimsSet.Builder jwtClaimsSetBuilder, return super.handleCustomClaims(jwtClaimsSetBuilder, tokenReqMessageContext); } + @Override + public JWTClaimsSet handleCustomClaims(JWTClaimsSet.Builder jwtClaimsSet, OAuthAuthzReqMessageContext + authzReqMessageContext) throws IdentityOAuth2Exception { + try { + if (IdentityCommonUtil.getRegulatoryFromSPMetaData( + authzReqMessageContext.getAuthorizationReqDTO().getConsumerKey())) { + Map claims = new HashMap<>(); + JWTClaimsSet claimsSet = getJwtClaimsFromSuperClass(jwtClaimsSet, authzReqMessageContext); + if (claimsSet != null) { + for (Map.Entry claimEntry : claimsSet.getClaims().entrySet()) { + claims.put(claimEntry.getKey(), claimEntry.getValue()); + } + } + updateSubClaim(authzReqMessageContext, claims); + for (Map.Entry claimEntry : claims.entrySet()) { + jwtClaimsSet.claim(claimEntry.getKey(), claimEntry.getValue()); + } + return jwtClaimsSet.build(); + } + } catch (OpenBankingException e) { + throw new IdentityOAuth2Exception(e.getMessage(), e); + } + return getJwtClaimsFromSuperClass(jwtClaimsSet, authzReqMessageContext); + } + + /** + * Update the subject claim of the JWT claims set base on below configurations. + * 1. open_banking.identity.token.remove_tenant_domain_from_subject + * 2. open_banking.identity.token.remove_user_store_domain_from_subject + * + * @param authzReqMessageContext token request message context + * @param claims user claims in OIDC dialect as a map + */ + private void updateSubClaim(OAuthAuthzReqMessageContext authzReqMessageContext, Map claims) { + + Object removeTenantDomainConfig = + identityConfigurations.get(IdentityCommonConstants.REMOVE_TENANT_DOMAIN_FROM_SUBJECT); + boolean removeTenantDomain = removeTenantDomainConfig != null + && Boolean.parseBoolean(removeTenantDomainConfig.toString()); + + Object removeUserStoreDomainConfig = + identityConfigurations.get(IdentityCommonConstants.REMOVE_USER_STORE_DOMAIN_FROM_SUBJECT); + boolean removeUserStoreDomain = removeUserStoreDomainConfig != null + && Boolean.parseBoolean(removeUserStoreDomainConfig.toString()); + + String subClaim = authzReqMessageContext.getAuthorizationReqDTO().getUser() + .getUsernameAsSubjectIdentifier(removeUserStoreDomain, removeTenantDomain); + claims.put("sub", subClaim); + } + + @Generated(message = "Excluding from code coverage since it makes is used to return claims from the super class") + public JWTClaimsSet getJwtClaimsFromSuperClass(JWTClaimsSet.Builder jwtClaimsSetBuilder, + OAuthAuthzReqMessageContext oAuthAuthzReqMessageContext) + throws IdentityOAuth2Exception { + + return super.handleCustomClaims(jwtClaimsSetBuilder, oAuthAuthzReqMessageContext); + } + @Generated(message = "Excluding from code coverage since it makes is used to return claims from the super class") public JWTClaimsSet getJwtClaimsFromSuperClass(JWTClaimsSet.Builder jwtClaimsSetBuilder, OAuthTokenReqMessageContext tokenReqMessageContext) diff --git a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.identity/src/test/java/com/wso2/openbanking/accelerator/identity/claims/OBDefaultOIDCClaimsCallbackHandlerTest.java b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.identity/src/test/java/com/wso2/openbanking/accelerator/identity/claims/OBDefaultOIDCClaimsCallbackHandlerTest.java index 8b0e3466..d9396176 100644 --- a/open-banking-accelerator/components/com.wso2.openbanking.accelerator.identity/src/test/java/com/wso2/openbanking/accelerator/identity/claims/OBDefaultOIDCClaimsCallbackHandlerTest.java +++ b/open-banking-accelerator/components/com.wso2.openbanking.accelerator.identity/src/test/java/com/wso2/openbanking/accelerator/identity/claims/OBDefaultOIDCClaimsCallbackHandlerTest.java @@ -38,7 +38,9 @@ import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext; import org.wso2.carbon.identity.oauth2.dto.OAuth2AccessTokenReqDTO; +import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeReqDTO; import org.wso2.carbon.identity.oauth2.model.HttpRequestHeader; import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; @@ -64,7 +66,7 @@ public class OBDefaultOIDCClaimsCallbackHandlerTest { private OBDefaultOIDCClaimsCallbackHandler obDefaultOIDCClaimsCallbackHandler; @BeforeClass - public void beforeClass() { + public void beforeClass() throws OpenBankingException { Map configMap = new HashMap<>(); configMap.put(IdentityCommonConstants.CONSENT_ID_CLAIM_NAME, "consent_id"); @@ -74,6 +76,7 @@ public void beforeClass() { mockStatic(FrameworkUtils.class); mockStatic(IdentityCommonUtil.class); + PowerMockito.when(IdentityCommonUtil.getRegulatoryFromSPMetaData("123")).thenReturn(true); when(FrameworkUtils.getMultiAttributeSeparator()).thenReturn(MULTI_ATTRIBUTE_SEPARATOR_DEFAULT); obDefaultOIDCClaimsCallbackHandler = Mockito.spy(OBDefaultOIDCClaimsCallbackHandler.class); } @@ -142,5 +145,22 @@ public void testHandleCustomClaims() throws OpenBankingException, IdentityOAuth2 assertEquals("{x5t#S256=807-E8KgUMV6dRHTQi1_QYo5eyPvjmjbxCtunbFixV0}", jwtClaimsSet.getClaim( "cnf").toString()); assertEquals("aaa@gold.com", jwtClaimsSet.getClaim("sub")); + + OAuth2AuthorizeReqDTO oAuth2AuthorizeReqDTO = new OAuth2AuthorizeReqDTO(); + OAuthAuthzReqMessageContext oAuthAuthzReqMessageContext = + new OAuthAuthzReqMessageContext(oAuth2AuthorizeReqDTO); + oAuthAuthzReqMessageContext.setAuthorizationReqDTO(oAuth2AuthorizeReqDTO); + + oAuth2AuthorizeReqDTO.setUser(authenticatedUser); + + oAuth2AuthorizeReqDTO.setConsumerKey("123"); + PowerMockito.when(jwtClaimsSetInitial.getClaims()).thenReturn(new SingletonMap("scope", "test")); + Mockito.doReturn(jwtClaimsSetInitial).when(obDefaultOIDCClaimsCallbackHandler) + .getJwtClaimsFromSuperClass(jwtClaimsSetBuilder, oAuthAuthzReqMessageContext); + JWTClaimsSet jwtClaimsSet2 = obDefaultOIDCClaimsCallbackHandler.handleCustomClaims(jwtClaimsSetBuilder, + oAuthAuthzReqMessageContext); + + assertEquals("aaa@gold.com@carbon.super", jwtClaimsSet2.getClaim("sub")); + } }