diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/ClaimsUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/ClaimsUtil.java index e611d36715..3f2a78bfc2 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/ClaimsUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/ClaimsUtil.java @@ -19,6 +19,7 @@ package org.wso2.carbon.identity.oauth2.util; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -29,7 +30,9 @@ import org.opensaml.saml.saml2.core.AttributeStatement; import org.w3c.dom.Element; import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException; import org.wso2.carbon.identity.application.common.model.ClaimConfig; @@ -294,30 +297,59 @@ private static List getRequestedLocalClaims(ClaimMapping[] spClaimMappin /** * Handle claims from identity provider based on claim configurations. * - * @param identityProvider Identity Provider + * @param identityProvider Identity Provider. * @param attributes Relevant Claims coming from IDP * @param tenantDomain Tenant Domain. * @param tokenReqMsgCtx Token request message context. - * @return mapped local claims. - * @throws IdentityException - * @throws IdentityApplicationManagementException + * @return Mapped local claims. + * @throws IdentityException If an error occurred while handling claim mappings. + * @throws IdentityApplicationManagementException If an error occurred while getting service provider. + * @deprecated Use {@link #handleClaimMapping(IdentityProvider, Map, String, OAuthTokenReqMessageContext, boolean)}. + */ + @Deprecated + public static Map handleClaimMapping(IdentityProvider identityProvider, + Map attributes, String tenantDomain, + OAuthTokenReqMessageContext tokenReqMsgCtx) + throws IdentityException, IdentityApplicationManagementException { + + return handleClaimMapping(identityProvider, attributes, tenantDomain, tokenReqMsgCtx, false); + } + + /** + * Handle claims from identity provider based on claim configurations. + * + * @param identityProvider Identity Provider + * @param attributes Relevant Claims coming from IDP + * @param tenantDomain Tenant Domain. + * @param tokenReqMsgCtx Token request message context. + * @param resolveIdPGroupAssignments Whether resolving IdP Group assignments needed. + * @return Mapped local claims. + * @throws IdentityException If an error occurred while handling claim mappings. + * @throws IdentityApplicationManagementException If an error occurred while getting service provider. */ public static Map handleClaimMapping(IdentityProvider identityProvider, - Map attributes, String tenantDomain, OAuthTokenReqMessageContext tokenReqMsgCtx) + Map attributes, String tenantDomain, + OAuthTokenReqMessageContext tokenReqMsgCtx, + boolean resolveIdPGroupAssignments) throws IdentityException, IdentityApplicationManagementException { + List assignedRoles = null; + ServiceProvider serviceProvider = getServiceProvider(tokenReqMsgCtx); + if (resolveIdPGroupAssignments) { + assignedRoles = getAssignedRolesFromIdPGroups(identityProvider, attributes, serviceProvider, + tenantDomain); + } boolean proxyUserAttributes = !OAuthServerConfiguration.getInstance() .isConvertOriginalClaimsFromAssertionsToOIDCDialect(); if (proxyUserAttributes) { setHasNonOIDCClaimsProperty(tokenReqMsgCtx); - return attributes; + return appendIdPMappedUserRolesAttributes(attributes, assignedRoles); } ClaimMapping[] idPClaimMappings = identityProvider.getClaimConfig().getClaimMappings(); Map claimsAfterIdpMapping; Map claimsAfterSPMapping = new HashMap<>(); - ServiceProvider serviceProvider = getServiceProvider(tokenReqMsgCtx); if (ArrayUtils.isNotEmpty(idPClaimMappings)) { if (log.isDebugEnabled()) { @@ -378,7 +410,36 @@ public static Map handleClaimMapping(IdentityProvider identityPr } } } - return claimsAfterSPMapping; + return appendIdPMappedUserRolesAttributes(claimsAfterSPMapping, assignedRoles); + } + + private static List getAssignedRolesFromIdPGroups(IdentityProvider identityProvider, + Map attributes, + ServiceProvider serviceProvider, + String tenantDomain) throws FrameworkException { + + if (serviceProvider == null || MapUtils.isEmpty(attributes)) { + return new ArrayList<>(); + } + String applicationId = serviceProvider.getApplicationResourceId(); + + String idpGroupClaimURI = FrameworkUtils.getEffectiveIdpGroupClaimUri(identityProvider, tenantDomain); + if (StringUtils.isBlank(idpGroupClaimURI)) { + return new ArrayList<>(); + } + + return FrameworkUtils.getAppAssociatedRolesFromFederatedUserAttributes(attributes, identityProvider, + applicationId, idpGroupClaimURI, tenantDomain); + } + + private static Map appendIdPMappedUserRolesAttributes(Map attributes, + List assignedRoles) { + + if (CollectionUtils.isNotEmpty(assignedRoles)) { + attributes.put(FrameworkConstants.IDP_MAPPED_USER_ROLES, + String.join(FrameworkUtils.getMultiAttributeSeparator(), assignedRoles)); + } + return attributes; } /** 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 28ecc6a82e..21624bcc0c 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 @@ -28,6 +28,7 @@ import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException; import org.wso2.carbon.identity.application.common.model.ClaimMapping; @@ -172,6 +173,8 @@ private Map getUserClaimsInOIDCDialect(OAuthTokenReqMessageConte // Get claim map from the cached attributes userClaimsInOIDCDialect = getOIDCClaimsFromUserAttributes(userAttributes, requestMsgCtx); } + // Remove the identityProviderMappedUserRoles claim since it is not an OIDC claim. + userClaimsInOIDCDialect.remove(FrameworkConstants.IDP_MAPPED_USER_ROLES); Object hasNonOIDCClaimsProperty = requestMsgCtx.getProperty(OIDCConstants.HAS_NON_OIDC_CLAIMS); if (isPreserverClaimUrisInAssertion(requestMsgCtx) || (hasNonOIDCClaimsProperty != null diff --git a/pom.xml b/pom.xml index c14c5649e1..a99944c9dd 100644 --- a/pom.xml +++ b/pom.xml @@ -967,7 +967,7 @@ [1.0.1, 2.0.0) - 7.7.114 + 7.7.140 [5.25.234, 8.0.0) [2.0.0, 3.0.0)