From 0006d2ae6fef91afd376e3dbc8db44454c05d3a4 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Tue, 10 Oct 2023 21:48:38 +0530 Subject: [PATCH 01/29] add policy handlers --- .../internal/OAuthComponentServiceHolder.java | 42 +++++ .../DefaultOAuth2ScopeValidator.java | 158 ++++++++++++++++++ .../policyhandler/PolicyContext.java | 43 +++++ .../ScopeValidatorPolicyHandler.java | 14 ++ .../ScopeValidatorPolicyHandlerException.java | 25 +++ .../impl/NoPolicyPolicyHandler.java | 36 ++++ .../impl/RoleBasedPolicyHandler.java | 42 +++++ 7 files changed, 360 insertions(+) create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java index 5103aca8b7d..2aff1538917 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java @@ -30,6 +30,7 @@ import org.wso2.carbon.identity.oauth2.dao.AccessTokenDAO; import org.wso2.carbon.identity.oauth2.dao.TokenManagementDAO; import org.wso2.carbon.identity.oauth2.token.handlers.response.AccessTokenResponseHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; import org.wso2.carbon.identity.oauth2.validators.scope.ScopeValidator; import org.wso2.carbon.identity.organization.management.service.OrganizationUserResidentResolverService; import org.wso2.carbon.identity.role.mgt.core.RoleManagementService; @@ -56,6 +57,7 @@ public class OAuthComponentServiceHolder { private List tokenBindingMetaDataDTOs = new ArrayList<>(); private OAuthAdminServiceImpl oAuthAdminService; private List scopeValidators = new ArrayList<>(); + private List scopeValidatorPolicyHandlers = new ArrayList<>(); private Map oAuthApplicationMgtListeners = new TreeMap<>(); private RoleManagementService roleManagementService; private OrganizationUserResidentResolverService organizationUserResidentResolverService; @@ -103,6 +105,46 @@ public void setScopeValidators(List scopeValidators) { this.scopeValidators = scopeValidators; } + /** + * Get the list of scope validator policy handler implementations available. + * + * @return ScopeValidatorPolicyHandler returns a list ot scope validator policy handler. + */ + public List getScopeValidatorPolicyHandlers() { + + return scopeValidatorPolicyHandlers; + } + + /** + * Add scope validator policy handler implementation. + * + * @param scopeValidatorPolicyHandler Scope validator policy handler implementation. + */ + public void addScopeValidatorPolicyHandler(ScopeValidatorPolicyHandler scopeValidatorPolicyHandler) { + + scopeValidatorPolicyHandlers.add(scopeValidatorPolicyHandler); + } + + /** + * Remove scope validator policy handler implementation. + * + * @param scopeValidatorPolicyHandler Scope validator policy handler implementation. + */ + public void removeScopeValidatorPolicyHandler(ScopeValidatorPolicyHandler scopeValidatorPolicyHandler) { + + scopeValidatorPolicyHandlers.remove(scopeValidatorPolicyHandler); + } + + /** + * Set a list of scope validator policy handler implementations. + * + * @param scopeValidatorPolicyHandlers List of Scope validator policy handler implementation. + */ + public void setScopeValidatorPolicyHandlers(List scopeValidatorPolicyHandlers) { + + this.scopeValidatorPolicyHandlers = scopeValidatorPolicyHandlers; + } + private OAuthComponentServiceHolder() { } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java new file mode 100644 index 00000000000..8fae96d3466 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -0,0 +1,158 @@ +package org.wso2.carbon.identity.oauth2.validators; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.opensaml.xmlsec.signature.P; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException; +import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; +import org.wso2.carbon.identity.oauth.IdentityOAuthAdminException; +import org.wso2.carbon.identity.oauth.OAuthAdminServiceImpl; +import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder; +import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext; +import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; +import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.PolicyContext; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandlerException; +import org.wso2.carbon.identity.oauth2.validators.scope.ScopeValidator; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public class DefaultOAuth2ScopeValidator { + + public static final String CLIENT_TYPE = "oauth2"; + + private static final Log LOG = LogFactory.getLog(DefaultOAuth2ScopeValidator.class); + + public List validateScope(OAuthAuthzReqMessageContext authzReqMessageContext) + throws IdentityOAuth2Exception { + + if (isScopesEmpty(authzReqMessageContext.getAuthorizationReqDTO().getScopes())) { + if (LOG.isDebugEnabled()) { + LOG.debug("Requested scope list is empty. Therefore, default OAuth2 scope validation is skipped."); + } + return new ArrayList<>(); + } + List requestedScopes = Arrays.asList(authzReqMessageContext.getAuthorizationReqDTO().getScopes()); + String tenantDomain = authzReqMessageContext.getAuthorizationReqDTO().getTenantDomain(); + String clientId = authzReqMessageContext.getAuthorizationReqDTO().getConsumerKey(); + String appId = getApplicationId(clientId, tenantDomain); + return getAuthorizedScopes(requestedScopes, authzReqMessageContext.getAuthorizationReqDTO().getUser(), appId, + tenantDomain); + } + + public List validateScope(OAuthTokenReqMessageContext tokenReqMessageContext) + throws IdentityOAuth2Exception { + + if (isScopesEmpty(tokenReqMessageContext.getScope())) { + if (LOG.isDebugEnabled()) { + LOG.debug("Requested scope list is empty. Therefore, default OAuth2 scope validation is skipped."); + } + return new ArrayList<>(); + } + List requestedScopes = Arrays.asList(tokenReqMessageContext.getScope()); + String tenantDomain = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getTenantDomain(); + String clientId = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getClientId(); + String appId = getApplicationId(clientId, tenantDomain); + return getAuthorizedScopes(requestedScopes, tokenReqMessageContext.getAuthorizedUser(), appId, tenantDomain); + } + + private List getAuthorizedScopes(List requestedScopes, AuthenticatedUser authenticatedUser, + String appId, String tenantDomain) throws IdentityOAuth2Exception { + + // Filter OIDC scopes and add to approved scopes list. + if (LOG.isDebugEnabled()) { + LOG.debug("Filtering OIDC scopes from requested scopes: " + StringUtils.join(requestedScopes, " ")); + } + Set requestedOIDCScopes = getRequestedOIDCScopes(tenantDomain, requestedScopes); + if (LOG.isDebugEnabled()) { + LOG.debug("Requested OIDC scopes : " + StringUtils.join(requestedOIDCScopes, " ")); + } + /* Here, we add the user-requested OIDC scopes to the approved scope list and remove from requested scope list + before we pass the scopes to the authorization service. Otherwise, the OIDC scopes will be dropped from + the approved scope list. */ + List approvedScopes = new ArrayList<>(requestedOIDCScopes); + requestedScopes = removeOIDCScopes(requestedScopes, requestedOIDCScopes); + Map> policies = getAuthorizedScopes(appId, tenantDomain); + if (policies == null) { + return new ArrayList<>(); + } + List scopeValidatorPolicyHandlers = + OAuthComponentServiceHolder.getInstance().getScopeValidatorPolicyHandlers(); + Map> validatedScopesByHandler = new HashMap<>(); + for (Map.Entry> entry : policies.entrySet()) { + String policyId = entry.getKey(); + List authorizedScopes = entry.getValue(); + + for (ScopeValidatorPolicyHandler scopeValidatorPolicyHandler : scopeValidatorPolicyHandlers) { + if (scopeValidatorPolicyHandler.canHandle(policyId)) { + PolicyContext policyContext = new PolicyContext(); + policyContext.setAuthenticatedUser(authenticatedUser); + policyContext.setAppId(appId); + policyContext.setValidatedScopesByHandler(validatedScopesByHandler); + List validatedScopes = null; + try { + validatedScopes = scopeValidatorPolicyHandler.validateScopes(authorizedScopes, + requestedScopes, policyContext); + } catch (ScopeValidatorPolicyHandlerException e) { + throw new IdentityOAuth2Exception("Error while validating policies roles from " + + "authorization service.", e); + } + approvedScopes.addAll(validatedScopes); + validatedScopesByHandler.put(scopeValidatorPolicyHandler.getName(), validatedScopes); + } + } + } + return approvedScopes; + } + + private Map> getAuthorizedScopes(String appId, String tenantDomain) { + + // TODO : get authorized scopes + return null; + } + + private Set getRequestedOIDCScopes(String tenantDomain, List requestedScopes) + throws IdentityOAuth2Exception { + + OAuthAdminServiceImpl oAuthAdminServiceImpl = OAuth2ServiceComponentHolder.getInstance().getOAuthAdminService(); + try { + List oidcScopes = oAuthAdminServiceImpl.getRegisteredOIDCScope(tenantDomain); + return requestedScopes.stream().distinct().filter(oidcScopes::contains).collect(Collectors.toSet()); + } catch (IdentityOAuthAdminException e) { + throw new RuntimeException(e); + } + } + + private List removeOIDCScopes(List requestedScopes, Set oidcScopes) { + + return requestedScopes.stream().distinct().filter(s -> !oidcScopes.contains(s)).collect(Collectors.toList()); + } + + private String getApplicationId(String clientId, String tenantName) throws IdentityOAuth2Exception { + + ApplicationManagementService applicationMgtService = OAuth2ServiceComponentHolder.getApplicationMgtService(); + try { + return applicationMgtService.getApplicationResourceIDByInboundKey(clientId, CLIENT_TYPE, tenantName); + } catch (IdentityApplicationManagementException e) { + throw new IdentityOAuth2Exception("Error while retrieving application resource id for client : " + + clientId + " tenant : " + tenantName, e); + } + } + + private boolean isScopesEmpty(String[] scopes) { + + return ArrayUtils.isEmpty(scopes); + } + +} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java new file mode 100644 index 00000000000..19e554b3939 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java @@ -0,0 +1,43 @@ +package org.wso2.carbon.identity.oauth2.validators.policyhandler; + +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; + +import java.util.List; +import java.util.Map; + +public class PolicyContext { + + private AuthenticatedUser authenticatedUser; + private String appId; + private Map> validatedScopesByHandler; + + public AuthenticatedUser getAuthenticatedUser() { + + return authenticatedUser; + } + + public void setAuthenticatedUser(AuthenticatedUser authenticatedUser) { + + this.authenticatedUser = authenticatedUser; + } + + public String getAppId() { + + return appId; + } + + public void setAppId(String appId) { + + this.appId = appId; + } + + public Map> getValidatedScopesByHandler() { + + return validatedScopesByHandler; + } + + public void setValidatedScopesByHandler(Map> validatedScopesByHandler) { + + this.validatedScopesByHandler = validatedScopesByHandler; + } +} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java new file mode 100644 index 00000000000..83066fc36a7 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java @@ -0,0 +1,14 @@ +package org.wso2.carbon.identity.oauth2.validators.policyhandler; + +import java.util.List; + +public interface ScopeValidatorPolicyHandler { + + boolean canHandle(String policyId); + List validateScopes(List requestedScopes, List policyAuthorizedScopes, + PolicyContext policyContext) throws ScopeValidatorPolicyHandlerException; + String getPolicyID(); + + String getName(); + +} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java new file mode 100644 index 00000000000..c18ae3e6bd3 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java @@ -0,0 +1,25 @@ +package org.wso2.carbon.identity.oauth2.validators.policyhandler; + +public class ScopeValidatorPolicyHandlerException extends Exception { + + /** + * Constructs a new exception with an error message. + * + * @param message The detail message. + */ + public ScopeValidatorPolicyHandlerException(String message) { + + super(message); + } + + /** + * Constructs a new exception with the message and cause. + * + * @param message The detail message. + * @param cause The cause. + */ + public ScopeValidatorPolicyHandlerException(String message, Throwable cause) { + + super(message, cause); + } +} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java new file mode 100644 index 00000000000..6df1686b4a7 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java @@ -0,0 +1,36 @@ +package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; + +import org.wso2.carbon.identity.oauth2.validators.policyhandler.PolicyContext; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandlerException; + +import java.util.List; +import java.util.stream.Collectors; + +public class NoPolicyPolicyHandler implements ScopeValidatorPolicyHandler { + + @Override + public boolean canHandle(String policyId) { + + return getPolicyID().equals(policyId); + } + + @Override + public List validateScopes(List requestedScopes, List policyAuthorizedScopes, + PolicyContext policyContext) throws ScopeValidatorPolicyHandlerException { + + return requestedScopes.stream().filter(policyAuthorizedScopes::contains).collect(Collectors.toList()); + } + + @Override + public String getPolicyID() { + + return "NoPolicy"; + } + + @Override + public String getName() { + + return "NoPolicyPolicyHandler"; + } +} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java new file mode 100644 index 00000000000..0e289e83500 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java @@ -0,0 +1,42 @@ +package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; + +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.PolicyContext; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandlerException; + +import java.util.List; +import java.util.stream.Collectors; + +public class RoleBasedPolicyHandler implements ScopeValidatorPolicyHandler { + + @Override + public boolean canHandle(String policyId) { + + return getPolicyID().equals(policyId); + } + + @Override + public List validateScopes(List requestedScopes, List policyAuthorizedScopes, + PolicyContext policyContext) throws ScopeValidatorPolicyHandlerException { + + return requestedScopes.stream().filter(policyAuthorizedScopes::contains).collect(Collectors.toList()); + } + + private List getApplicationRoles(AuthenticatedUser authenticatedUser, String appId) { + + return null; + } + + @Override + public String getPolicyID() { + + return "RBAC"; + } + + @Override + public String getName() { + + return "RoleBasedPolicyHandler"; + } +} From 46756df14f0bbda20d102de5b3c47e8b4c672aa3 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Thu, 12 Oct 2023 09:00:22 +0530 Subject: [PATCH 02/29] add new scope validtaor --- .../authz/AuthorizationHandlerManager.java | 76 ++++++++++-- .../handlers/AbstractResponseTypeHandler.java | 5 +- .../internal/OAuth2ServiceComponent.java | 5 + .../oauth2/token/AccessTokenIssuer.java | 80 ++++++++++--- .../AbstractAuthorizationGrantHandler.java | 5 +- .../identity/oauth2/util/OAuth2Util.java | 5 + .../DefaultOAuth2ScopeValidator.java | 37 +++++- .../policyhandler/PolicyContext.java | 3 + .../ScopeValidatorPolicyHandler.java | 3 + .../ScopeValidatorPolicyHandlerException.java | 3 + .../impl/NoPolicyPolicyHandler.java | 3 + .../impl/RoleBasedPolicyHandler.java | 110 +++++++++++++++++- 12 files changed, 302 insertions(+), 33 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java index a02d0cd4aaa..299b9e23c1c 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java @@ -42,6 +42,7 @@ import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeRespDTO; import org.wso2.carbon.identity.oauth2.model.OAuth2Parameters; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; +import org.wso2.carbon.identity.oauth2.validators.DefaultOAuth2ScopeValidator; import org.wso2.carbon.identity.oauth2.validators.JDBCPermissionBasedInternalScopeValidator; import org.wso2.carbon.identity.oauth2.validators.RoleBasedInternalScopeValidator; import org.wso2.carbon.utils.CarbonUtils; @@ -272,19 +273,28 @@ private void validateRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, ResponseTypeHandler authzHandler) throws IdentityOAuth2Exception, IdentityOAuth2UnauthorizedScopeException { + boolean isScopeValidationOldBehaviourEnabled = OAuth2Util.isScopeValidationOldBehaviourEnabled(); // Get allowed scopes that are specified in the server level. List requestedAllowedScopes = getAllowedScopesFromRequestedScopes(authzReqMsgCtx); // Remove the system level allowed scopes from requested scopes for further validation. removeAllowedScopesFromRequestedScopes(authzReqMsgCtx, requestedAllowedScopes); - // If it is management app, we validate internal scopes in the requested scopes. - String[] authorizedInternalScopes = new String[0]; - log.debug("Handling the internal scope validation."); - authorizedInternalScopes = getAuthorizedInternalScopes(authzReqMsgCtx); + List authorizedScopes = null; + if (isScopeValidationOldBehaviourEnabled) { + // If it is management app, we validate internal scopes in the requested scopes. + String[] authorizedInternalScopes = new String[0]; + log.debug("Handling the internal scope validation."); + authorizedInternalScopes = getAuthorizedInternalScopes(authzReqMsgCtx); + + // Remove the internal scopes from requested scopes for further validation. + removeInternalScopesFromRequestedScopes(authzReqMsgCtx); + // Adding the authorized internal scopes to tokReqMsgCtx for any special validators to use. + authzReqMsgCtx.setAuthorizedInternalScopes(authorizedInternalScopes); + } else { - // Remove the internal scopes from requested scopes for further validation. - removeInternalScopesFromRequestedScopes(authzReqMsgCtx); - // Adding the authorized internal scopes to tokReqMsgCtx for any special validators to use. - authzReqMsgCtx.setAuthorizedInternalScopes(authorizedInternalScopes); + // Engage new scope validator + authorizedScopes = getAuthorizedScopes(authzReqMsgCtx); + removeAuthorizedScopesFromRequestedScopes(authzReqMsgCtx, authorizedScopes); + } boolean isDropUnregisteredScopes = OAuthServerConfiguration.getInstance().isDropUnregisteredScopes(); if (isDropUnregisteredScopes) { if (log.isDebugEnabled()) { @@ -296,8 +306,12 @@ private void validateRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, boolean isValid = validateScopes(authzReqMsgCtx, authzHandler); boolean isValidatedScopesContainsInRequestedScopes = isValidatedScopesContainsInRequestedScopes(authzReqMsgCtx); if (isValid && isValidatedScopesContainsInRequestedScopes) { - // Add authorized internal scopes to the request for sending in the response. - addAuthorizedInternalScopes(authzReqMsgCtx, authzReqMsgCtx.getAuthorizedInternalScopes()); + if (isScopeValidationOldBehaviourEnabled) { + // Add authorized internal scopes to the request for sending in the response. + addAuthorizedInternalScopes(authzReqMsgCtx, authzReqMsgCtx.getAuthorizedInternalScopes()); + } else { + addAuthorizedScopes(authzReqMsgCtx, authorizedScopes); + } // Add scopes that filtered from the allowed scopes list. addAllowedScopes(authzReqMsgCtx, requestedAllowedScopes.toArray(new String[0])); } else { @@ -359,6 +373,19 @@ private String[] getAuthorizedInternalScopes(OAuthAuthzReqMessageContext authzRe return authorizedInternalScopes; } + /** + * get authorized scopes. + * + * @param authzReqMsgCtx authzReqMsgCtx + * @return - authorizedInternalScopes scopes list + */ + private List getAuthorizedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx) + throws IdentityOAuth2Exception { + + DefaultOAuth2ScopeValidator scopeValidator = new DefaultOAuth2ScopeValidator(); + return scopeValidator.validateScope(authzReqMsgCtx); + } + /** * Eemove internal scopes from requested scopes. * @@ -379,6 +406,27 @@ private void removeInternalScopesFromRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx.getAuthorizationReqDTO().setScopes(scopes.toArray(new String[0])); } + /** + * Remove authorized scopes from requested scopes. + * + * @param authzReqMsgCtx authzReqMsgCtx + * @param authorizedScopes Authorized Scopes + */ + private void removeAuthorizedScopesFromRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, + List authorizedScopes) { + + if (authzReqMsgCtx.getAuthorizationReqDTO().getScopes() == null) { + return; + } + List scopes = new ArrayList<>(); + for (String scope : authzReqMsgCtx.getAuthorizationReqDTO().getScopes()) { + if (!authorizedScopes.contains(scope)) { + scopes.add(scope); + } + } + authzReqMsgCtx.getAuthorizationReqDTO().setScopes(scopes.toArray(new String[0])); + } + /** * Remove the system level allowed scopes from requested scopes. * @@ -419,6 +467,14 @@ private void addAuthorizedInternalScopes(OAuthAuthzReqMessageContext authzReqMsg authzReqMsgCtx.setApprovedScope(scopesToReturn); } + private void addAuthorizedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, List authorizedScopes) { + + String[] scopes = authzReqMsgCtx.getApprovedScope(); + String[] scopesToReturn = (String[]) ArrayUtils.addAll(scopes, authorizedScopes.toArray()); + authzReqMsgCtx.setApprovedScope(scopesToReturn); + } + + private void addRequestedOIDCScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, String[] requestedOIDCScopes) { Set scopesToReturn = new HashSet<>(Arrays.asList(authzReqMsgCtx.getApprovedScope())); diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java index bc1b5a78bb0..8cf1e441acb 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java @@ -234,6 +234,9 @@ public OAuth2AuthorizeRespDTO initResponse(OAuthAuthzReqMessageContext oauthAuth private boolean hasValidationByApplicationScopeValidatorsFailed(OAuthAuthzReqMessageContext authzReqMessageContext) throws IdentityOAuth2Exception { - return !Oauth2ScopeUtils.validateByApplicationScopeValidator(null, authzReqMessageContext); + if (OAuth2Util.isScopeValidationOldBehaviourEnabled()) { + return !Oauth2ScopeUtils.validateByApplicationScopeValidator(null, authzReqMessageContext); + } + return true; } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java index a6b3289470d..ff8ba20d89f 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java @@ -77,6 +77,9 @@ import org.wso2.carbon.identity.oauth2.token.bindings.impl.SSOSessionBasedTokenBinder; import org.wso2.carbon.identity.oauth2.token.handlers.claims.JWTAccessTokenClaimProvider; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.NoPolicyPolicyHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.RoleBasedPolicyHandler; import org.wso2.carbon.identity.oauth2.validators.scope.RoleBasedScopeIssuer; import org.wso2.carbon.identity.oauth2.validators.scope.ScopeValidator; import org.wso2.carbon.identity.openidconnect.OpenIDConnectClaimFilter; @@ -331,6 +334,8 @@ protected void activate(ComponentContext context) { bundleContext.registerService(OAuth2ScopeService.class.getName(), oAuth2ScopeService, null); // Registering OAuth2ScopeService under ScopeService interface as the default service. bundleContext.registerService(ScopeMetadataService.class, oAuth2ScopeService, null); + bundleContext.registerService(ScopeValidatorPolicyHandler.class, new RoleBasedPolicyHandler(), null); + bundleContext.registerService(ScopeValidatorPolicyHandler.class, new NoPolicyPolicyHandler(), null); // Note : DO NOT add any activation related code below this point, // to make sure the server doesn't start up if any activation failures occur diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java index c442520c1c3..67d5581fc52 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java @@ -67,6 +67,7 @@ import org.wso2.carbon.identity.oauth2.token.handlers.grant.AuthorizationGrantHandler; import org.wso2.carbon.identity.oauth2.token.handlers.response.AccessTokenResponseHandler; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; +import org.wso2.carbon.identity.oauth2.validators.DefaultOAuth2ScopeValidator; import org.wso2.carbon.identity.oauth2.validators.JDBCPermissionBasedInternalScopeValidator; import org.wso2.carbon.identity.oauth2.validators.RoleBasedInternalScopeValidator; import org.wso2.carbon.identity.openidconnect.IDTokenBuilder; @@ -596,6 +597,7 @@ private Optional getAuthzGrantCacheEntryFromAuthzC private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception { + boolean isScopeValidationOldBehaviourEnabled = OAuth2Util.isScopeValidationOldBehaviourEnabled(); OAuth2AccessTokenReqDTO tokenReqDTO = tokReqMsgCtx.getOauth2AccessTokenReqDTO(); String grantType = tokenReqDTO.getGrantType(); if (GrantType.AUTHORIZATION_CODE.toString().equals(grantType)) { @@ -645,6 +647,7 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I List requestedAllowedScopes = new ArrayList<>(); String[] authorizedInternalScopes = new String[0]; String[] requestedScopes = tokReqMsgCtx.getScope(); + List authorizedScopes = null; if (GrantType.CLIENT_CREDENTIALS.toString().equals(grantType) && !isManagementApp) { log.debug("Application is not configured as Management App and the grant type is client credentials. " + "Hence skipping internal scope validation to stop issuing internal scopes for the client : " + @@ -676,15 +679,23 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I if (log.isDebugEnabled()) { log.debug("Handling the internal scope validation."); } - // Execute Internal SCOPE Validation. - JDBCPermissionBasedInternalScopeValidator scopeValidator = new JDBCPermissionBasedInternalScopeValidator(); - authorizedInternalScopes = scopeValidator.validateScope(tokReqMsgCtx); - // Execute internal console scopes validation. - if (IdentityUtil.isSystemRolesEnabled()) { - RoleBasedInternalScopeValidator roleBasedInternalScopeValidator = new RoleBasedInternalScopeValidator(); - String[] roleBasedInternalConsoleScopes = roleBasedInternalScopeValidator.validateScope(tokReqMsgCtx); - authorizedInternalScopes = (String[]) ArrayUtils - .addAll(authorizedInternalScopes, roleBasedInternalConsoleScopes); + if (isScopeValidationOldBehaviourEnabled) { + // Execute Internal SCOPE Validation. + JDBCPermissionBasedInternalScopeValidator scopeValidator = + new JDBCPermissionBasedInternalScopeValidator(); + authorizedInternalScopes = scopeValidator.validateScope(tokReqMsgCtx); + // Execute internal console scopes validation. + if (IdentityUtil.isSystemRolesEnabled()) { + RoleBasedInternalScopeValidator roleBasedInternalScopeValidator = + new RoleBasedInternalScopeValidator(); + String[] roleBasedInternalConsoleScopes = roleBasedInternalScopeValidator + .validateScope(tokReqMsgCtx); + authorizedInternalScopes = (String[]) ArrayUtils + .addAll(authorizedInternalScopes, roleBasedInternalConsoleScopes); + } + } else { + // Engage new scope validator + authorizedScopes = getAuthorizedScopes(tokReqMsgCtx); } if (isManagementApp && GrantType.CLIENT_CREDENTIALS.toString().equals(grantType) && ArrayUtils.contains(requestedScopes, SYSTEM_SCOPE)) { @@ -705,10 +716,15 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I Those scopes should not send to the other scopes validators. Thus remove the scopes from the tokReqMsgCtx. Will be added to the response after executing the other scope validators. */ - removeInternalScopes(tokReqMsgCtx); + if (isScopeValidationOldBehaviourEnabled) { + removeInternalScopes(tokReqMsgCtx); + + // Adding the authorized internal scopes to tokReqMsgCtx for any special validators to use. + tokReqMsgCtx.setAuthorizedInternalScopes(authorizedInternalScopes); + } else { + removeAuthorizedScopes(tokReqMsgCtx, authorizedScopes); + } - // Adding the authorized internal scopes to tokReqMsgCtx for any special validators to use. - tokReqMsgCtx.setAuthorizedInternalScopes(authorizedInternalScopes); boolean isDropUnregisteredScopes = OAuthServerConfiguration.getInstance().isDropUnregisteredScopes(); if (isDropUnregisteredScopes) { @@ -725,7 +741,11 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I boolean isValidScope = authzGrantHandler.validateScope(tokReqMsgCtx); if (isValidScope) { // Add authorized internal scopes to the request for sending in the response. - addAuthorizedInternalScopes(tokReqMsgCtx, tokReqMsgCtx.getAuthorizedInternalScopes()); + if (isScopeValidationOldBehaviourEnabled) { + addAuthorizedInternalScopes(tokReqMsgCtx, tokReqMsgCtx.getAuthorizedInternalScopes()); + } else { + addAuthorizedScopes(tokReqMsgCtx, authorizedScopes); + } addAllowedScopes(tokReqMsgCtx, requestedAllowedScopes.toArray(new String[0])); if (LoggerUtils.isDiagnosticLogsEnabled()) { LoggerUtils.triggerDiagnosticLogEvent(new DiagnosticLog.DiagnosticLogBuilder( @@ -744,6 +764,13 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I return isValidScope; } + private List getAuthorizedScopes(OAuthTokenReqMessageContext tokReqMsgCtx) + throws IdentityOAuth2Exception { + + DefaultOAuth2ScopeValidator scopeValidator = new DefaultOAuth2ScopeValidator(); + return scopeValidator.validateScope(tokReqMsgCtx); + } + private List getScopeList(String[] scopes) { return ArrayUtils.isEmpty(scopes) ? Collections.emptyList() : Arrays.asList(scopes); @@ -925,6 +952,19 @@ private void addAuthorizedInternalScopes(OAuthTokenReqMessageContext tokReqMsgCt .distinct().toArray(String[]::new)); } + private void addAuthorizedScopes(OAuthTokenReqMessageContext tokReqMsgCtx, List authorizedScopes) { + + String[] scopes = tokReqMsgCtx.getScope(); + if (scopes == null) { + scopes = new String[0]; + } + if (authorizedScopes == null) { + authorizedScopes = new ArrayList<>(); + } + tokReqMsgCtx.setScope(Stream.concat(Arrays.stream(scopes), authorizedScopes.stream()) + .distinct().toArray(String[]::new)); + } + private void addRequestedOIDCScopes(OAuthTokenReqMessageContext tokReqMsgCtx, String[] requestedOIDCScopes) { @@ -960,6 +1000,20 @@ private void removeInternalScopes(OAuthTokenReqMessageContext tokReqMsgCtx) { tokReqMsgCtx.setScope(scopes.toArray(new String[0])); } + private void removeAuthorizedScopes(OAuthTokenReqMessageContext tokReqMsgCtx, List authorizedScopes) { + + if (tokReqMsgCtx.getScope() == null) { + return; + } + List scopes = new ArrayList<>(); + for (String scope : tokReqMsgCtx.getScope()) { + if (!authorizedScopes.contains(scope)) { + scopes.add(scope); + } + } + tokReqMsgCtx.setScope(scopes.toArray(new String[0])); + } + /** * Handle token binding for the grant type. * diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java index 345023bae42..4e3b03bc4bc 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java @@ -1041,7 +1041,10 @@ private OAuth2Service getOauth2Service() { private boolean hasValidationByApplicationScopeValidatorsFailed(OAuthTokenReqMessageContext tokenReqMsgContext) throws IdentityOAuth2Exception { - return !Oauth2ScopeUtils.validateByApplicationScopeValidator(tokenReqMsgContext, null); + if (OAuth2Util.isScopeValidationOldBehaviourEnabled()) { + return !Oauth2ScopeUtils.validateByApplicationScopeValidator(tokenReqMsgContext, null); + } + return true; } /** diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java index ea28e73f7ce..4c17601ece3 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java @@ -4960,4 +4960,9 @@ public static String[] extractCredentialsFromAuthzHeader(HttpServletRequest requ return OAuthUtils.decodeClientAuthenticationHeader(authorizationHeader); } + + public static boolean isScopeValidationOldBehaviourEnabled() { + + return false; + } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index 8fae96d3466..b08bc2b75f0 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -4,7 +4,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.opensaml.xmlsec.signature.P; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException; import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; @@ -18,16 +17,20 @@ import org.wso2.carbon.identity.oauth2.validators.policyhandler.PolicyContext; import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandlerException; -import org.wso2.carbon.identity.oauth2.validators.scope.ScopeValidator; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +/** + * DefaultOAuth2ScopeValidator + */ public class DefaultOAuth2ScopeValidator { public static final String CLIENT_TYPE = "oauth2"; @@ -100,7 +103,7 @@ private List getAuthorizedScopes(List requestedScopes, Authentic policyContext.setAuthenticatedUser(authenticatedUser); policyContext.setAppId(appId); policyContext.setValidatedScopesByHandler(validatedScopesByHandler); - List validatedScopes = null; + List validatedScopes; try { validatedScopes = scopeValidatorPolicyHandler.validateScopes(authorizedScopes, requestedScopes, policyContext); @@ -108,18 +111,42 @@ private List getAuthorizedScopes(List requestedScopes, Authentic throw new IdentityOAuth2Exception("Error while validating policies roles from " + "authorization service.", e); } - approvedScopes.addAll(validatedScopes); validatedScopesByHandler.put(scopeValidatorPolicyHandler.getName(), validatedScopes); } } } + + // If "NoPolicy" exists, add all its scopes to the result + Set scopes = new HashSet<>(validatedScopesByHandler.getOrDefault("NoPolicy", + Collections.emptyList())); + + // Separate "NoPolicy" and get the intersection of the rest of the scopes validated by other validators + List> otherHandlerScopes = new ArrayList<>(validatedScopesByHandler.values()); + otherHandlerScopes.remove(validatedScopesByHandler.get("NoPolicy")); + + List intersection = new ArrayList<>(); + if (!otherHandlerScopes.isEmpty()) { + intersection = otherHandlerScopes.get(0); + for (int i = 1; i < otherHandlerScopes.size(); i++) { + intersection = intersection.stream().filter(otherHandlerScopes.get(i)::contains) + .collect(Collectors.toList()); + } + } + scopes.addAll(intersection); + approvedScopes.addAll(scopes); return approvedScopes; } private Map> getAuthorizedScopes(String appId, String tenantDomain) { // TODO : get authorized scopes - return null; + Map> authorizedScopes = new HashMap<>(); + List scopes = new ArrayList<>(); + scopes.add("scope1"); + scopes.add("scope2"); + authorizedScopes.put("NoPolicy", scopes); + authorizedScopes.put("RBAC", scopes); + return authorizedScopes; } private Set getRequestedOIDCScopes(String tenantDomain, List requestedScopes) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java index 19e554b3939..7a17bc2fdc6 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java @@ -5,6 +5,9 @@ import java.util.List; import java.util.Map; +/** + * PolicyContext + */ public class PolicyContext { private AuthenticatedUser authenticatedUser; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java index 83066fc36a7..2bfc894b062 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java @@ -2,6 +2,9 @@ import java.util.List; +/** + * ScopeValidatorPolicyHandler + */ public interface ScopeValidatorPolicyHandler { boolean canHandle(String policyId); diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java index c18ae3e6bd3..5e8f45de74b 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java @@ -1,5 +1,8 @@ package org.wso2.carbon.identity.oauth2.validators.policyhandler; +/** + * ScopeValidatorPolicyHandlerException + */ public class ScopeValidatorPolicyHandlerException extends Exception { /** diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java index 6df1686b4a7..c5bfe99efd9 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java @@ -7,6 +7,9 @@ import java.util.List; import java.util.stream.Collectors; +/** + * NoPolicyPolicyHandler + */ public class NoPolicyPolicyHandler implements ScopeValidatorPolicyHandler { @Override diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java index 0e289e83500..a69daf05372 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java @@ -1,15 +1,34 @@ package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.util.OAuth2Util; +import org.wso2.carbon.identity.oauth2.validators.DefaultOAuth2ScopeValidator; import org.wso2.carbon.identity.oauth2.validators.policyhandler.PolicyContext; import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandlerException; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; +import org.wso2.carbon.user.core.NotImplementedException; +import org.wso2.carbon.user.core.common.AbstractUserStoreManager; +import org.wso2.carbon.user.core.common.Group; +import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.user.core.util.UserCoreUtil; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +/** + * RoleBasedPolicyHandler + */ public class RoleBasedPolicyHandler implements ScopeValidatorPolicyHandler { + private static final Log LOG = LogFactory.getLog(DefaultOAuth2ScopeValidator.class); + @Override public boolean canHandle(String policyId) { @@ -20,15 +39,100 @@ public boolean canHandle(String policyId) { public List validateScopes(List requestedScopes, List policyAuthorizedScopes, PolicyContext policyContext) throws ScopeValidatorPolicyHandlerException { - return requestedScopes.stream().filter(policyAuthorizedScopes::contains).collect(Collectors.toList()); + List userRoles = getUserRoles(policyContext.getAuthenticatedUser(), policyContext.getAppId()); + List associatedScopes = getAssociatedScopesForRoles(userRoles, + policyContext.getAuthenticatedUser().getTenantDomain()); + List filteredScopes = policyAuthorizedScopes.stream().filter(associatedScopes::contains) + .collect(Collectors.toList()); + return requestedScopes.stream().filter(filteredScopes::contains).collect(Collectors.toList()); } - private List getApplicationRoles(AuthenticatedUser authenticatedUser, String appId) { + private List getAssociatedScopesForRoles(List roles, String tenantDomain) { + // TODO : return null; } - @Override + private List getUserRoles(AuthenticatedUser authenticatedUser, String appId) { + + // TODO : Get hybrid user roles of the user + + // TODO: Get groups of the user + List groups; + try { + groups = getUserGroups(authenticatedUser); + } catch (IdentityOAuth2Exception e) { + throw new RuntimeException(e); + } + // TODO: Get roles of the groups + + // + + return null; + } + + /** + * Get the groups of the authenticated user. + * + * @param authenticatedUser Authenticated user. + * @return - Groups of the user. + */ + private List getUserGroups(AuthenticatedUser authenticatedUser) + throws IdentityOAuth2Exception { + + if (LOG.isDebugEnabled()) { + LOG.debug("Started group fetching for scope validation."); + } + List userGroups = new ArrayList<>(); + if (authenticatedUser.isFederatedUser()) { + // TODO: get federated user groups | at the moment, if the user is a federated user we skip the validation + return userGroups; + } + RealmService realmService = UserCoreUtil.getRealmService(); + try { + int tenantId = OAuth2Util.getTenantId(authenticatedUser.getTenantDomain()); + UserStoreManager userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager(); + List groups = + ((AbstractUserStoreManager) userStoreManager).getGroupListOfUser(authenticatedUser.getUserId(), + null, null); + // Exclude internal and application groups from the list. + for (Group group : groups) { + userGroups.add(group.getGroupName()); + } + } catch (UserIdNotFoundException e) { + throw new IdentityOAuth2Exception(e.getMessage(), e); + } catch (UserStoreException e) { + if (isDoGetGroupListOfUserNotImplemented(e)) { + return userGroups; + } + throw new IdentityOAuth2Exception(e.getMessage(), e); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Completed group fetching for scope validation."); + } + return userGroups; + } + + /** + * Check if the UserStoreException occurred due to the doGetGroupListOfUser method not being implemented. + * + * @param e UserStoreException. + * @return true if the UserStoreException was caused by the doGetGroupListOfUser method not being implemented, + * false otherwise. + */ + private boolean isDoGetGroupListOfUserNotImplemented(UserStoreException e) { + + Throwable cause = e.getCause(); + while (cause != null) { + if (cause instanceof NotImplementedException) { + return true; + } + cause = cause.getCause(); + } + return false; + } + + @Override public String getPolicyID() { return "RBAC"; From fa30e136726a5d45ced8bbfb8ac5ed4d13b51f91 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Thu, 12 Oct 2023 11:33:34 +0530 Subject: [PATCH 03/29] add system scope handling --- .../org/wso2/carbon/identity/oauth2/util/OAuth2Util.java | 2 +- .../oauth2/validators/DefaultOAuth2ScopeValidator.java | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java index 4c17601ece3..20356cb7a87 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java @@ -4963,6 +4963,6 @@ public static String[] extractCredentialsFromAuthzHeader(HttpServletRequest requ public static boolean isScopeValidationOldBehaviourEnabled() { - return false; + return true; } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index b08bc2b75f0..c48b0163432 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -28,6 +28,8 @@ import java.util.Set; import java.util.stream.Collectors; +import static org.wso2.carbon.identity.oauth2.Oauth2ScopeConstants.SYSTEM_SCOPE; + /** * DefaultOAuth2ScopeValidator */ @@ -86,6 +88,11 @@ private List getAuthorizedScopes(List requestedScopes, Authentic the approved scope list. */ List approvedScopes = new ArrayList<>(requestedOIDCScopes); requestedScopes = removeOIDCScopes(requestedScopes, requestedOIDCScopes); + if (requestedScopes.contains(SYSTEM_SCOPE)) { + // TODO : get all internal scopes + List allInternalScopes = new ArrayList<>(); + requestedScopes.addAll(allInternalScopes); + } Map> policies = getAuthorizedScopes(appId, tenantDomain); if (policies == null) { return new ArrayList<>(); From 34473ae51274eb9a845e1bf2c50b9fb017c989cd Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Mon, 16 Oct 2023 10:49:44 +0530 Subject: [PATCH 04/29] filter role by apps --- .../validators/policyhandler/impl/RoleBasedPolicyHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java index a69daf05372..e47016a8b9b 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java @@ -66,7 +66,7 @@ private List getUserRoles(AuthenticatedUser authenticatedUser, String ap } // TODO: Get roles of the groups - // + // TODO : Filter roles by app return null; } From e04fcde21fc66e7e6727e3e861934ca338112412 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Thu, 19 Oct 2023 11:42:50 +0530 Subject: [PATCH 05/29] add user role resolving --- .../org.wso2.carbon.identity.oauth/pom.xml | 12 + .../internal/OAuthComponentServiceHolder.java | 12 +- .../internal/OAuth2ServiceComponent.java | 72 ++++- .../OAuth2ServiceComponentHolder.java | 54 ++++ .../DefaultOAuth2ScopeValidator.java | 85 ++--- ...ntext.java => ScopeValidationContext.java} | 25 +- .../policyhandler/ScopeValidationHandler.java | 17 + ...a => ScopeValidationHandlerException.java} | 6 +- .../ScopeValidatorPolicyHandler.java | 17 - .../impl/M2MScopeValidationHandler.java | 39 +++ .../impl/NoPolicyPolicyHandler.java | 39 --- .../impl/NoPolicyScopeValidationHandler.java | 41 +++ .../impl/RoleBasedPolicyHandler.java | 146 --------- .../impl/RoleBasedScopeValidationHandler.java | 301 ++++++++++++++++++ pom.xml | 13 +- 15 files changed, 624 insertions(+), 255 deletions(-) rename components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/{PolicyContext.java => ScopeValidationContext.java} (71%) create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java rename components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/{ScopeValidatorPolicyHandlerException.java => ScopeValidationHandlerException.java} (68%) delete mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java delete mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java delete mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java diff --git a/components/org.wso2.carbon.identity.oauth/pom.xml b/components/org.wso2.carbon.identity.oauth/pom.xml index d7903f85490..edaa084cbad 100644 --- a/components/org.wso2.carbon.identity.oauth/pom.xml +++ b/components/org.wso2.carbon.identity.oauth/pom.xml @@ -329,6 +329,16 @@ jaxp-ri test + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.api.resource.mgt + provided + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.role.v2.mgt.core + provided + @@ -423,6 +433,8 @@ org.wso2.carbon.utils.multitenancy;version="${carbon.kernel.imp.pkg.version.range}", org.wso2.carbon.identity.multi.attribute.login.mgt.*; version="${carbon.identity.framework.imp.pkg.version.range}", + org.wso2.carbon.identity.api.resource.mgt; version="${carbon.identity.framework.imp.pkg.version.range}", + org.wso2.carbon.identity.role.v2.mgt.core; version="${carbon.identity.framework.imp.pkg.version.range}" !org.wso2.carbon.identity.oauth.internal, diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java index 2aff1538917..31579797db0 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java @@ -30,7 +30,7 @@ import org.wso2.carbon.identity.oauth2.dao.AccessTokenDAO; import org.wso2.carbon.identity.oauth2.dao.TokenManagementDAO; import org.wso2.carbon.identity.oauth2.token.handlers.response.AccessTokenResponseHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; import org.wso2.carbon.identity.oauth2.validators.scope.ScopeValidator; import org.wso2.carbon.identity.organization.management.service.OrganizationUserResidentResolverService; import org.wso2.carbon.identity.role.mgt.core.RoleManagementService; @@ -57,7 +57,7 @@ public class OAuthComponentServiceHolder { private List tokenBindingMetaDataDTOs = new ArrayList<>(); private OAuthAdminServiceImpl oAuthAdminService; private List scopeValidators = new ArrayList<>(); - private List scopeValidatorPolicyHandlers = new ArrayList<>(); + private List scopeValidatorPolicyHandlers = new ArrayList<>(); private Map oAuthApplicationMgtListeners = new TreeMap<>(); private RoleManagementService roleManagementService; private OrganizationUserResidentResolverService organizationUserResidentResolverService; @@ -110,7 +110,7 @@ public void setScopeValidators(List scopeValidators) { * * @return ScopeValidatorPolicyHandler returns a list ot scope validator policy handler. */ - public List getScopeValidatorPolicyHandlers() { + public List getScopeValidatorPolicyHandlers() { return scopeValidatorPolicyHandlers; } @@ -120,7 +120,7 @@ public List getScopeValidatorPolicyHandlers() { * * @param scopeValidatorPolicyHandler Scope validator policy handler implementation. */ - public void addScopeValidatorPolicyHandler(ScopeValidatorPolicyHandler scopeValidatorPolicyHandler) { + public void addScopeValidatorPolicyHandler(ScopeValidationHandler scopeValidatorPolicyHandler) { scopeValidatorPolicyHandlers.add(scopeValidatorPolicyHandler); } @@ -130,7 +130,7 @@ public void addScopeValidatorPolicyHandler(ScopeValidatorPolicyHandler scopeVali * * @param scopeValidatorPolicyHandler Scope validator policy handler implementation. */ - public void removeScopeValidatorPolicyHandler(ScopeValidatorPolicyHandler scopeValidatorPolicyHandler) { + public void removeScopeValidatorPolicyHandler(ScopeValidationHandler scopeValidatorPolicyHandler) { scopeValidatorPolicyHandlers.remove(scopeValidatorPolicyHandler); } @@ -140,7 +140,7 @@ public void removeScopeValidatorPolicyHandler(ScopeValidatorPolicyHandler scopeV * * @param scopeValidatorPolicyHandlers List of Scope validator policy handler implementation. */ - public void setScopeValidatorPolicyHandlers(List scopeValidatorPolicyHandlers) { + public void setScopeValidatorPolicyHandlers(List scopeValidatorPolicyHandlers) { this.scopeValidatorPolicyHandlers = scopeValidatorPolicyHandlers; } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java index ff8ba20d89f..7d3f05672d4 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java @@ -31,11 +31,13 @@ import org.osgi.service.component.annotations.ReferenceCardinality; import org.osgi.service.component.annotations.ReferencePolicy; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.api.resource.mgt.APIResourceManager; import org.wso2.carbon.identity.application.authentication.framework.ApplicationAuthenticationService; import org.wso2.carbon.identity.application.authentication.framework.AuthenticationDataPublisher; import org.wso2.carbon.identity.application.authentication.framework.AuthenticationMethodNameTranslator; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; +import org.wso2.carbon.identity.application.mgt.AuthorizedAPIManagementService; import org.wso2.carbon.identity.application.mgt.listener.ApplicationMgtListener; import org.wso2.carbon.identity.consent.server.configs.mgt.services.ConsentServerConfigsManagementService; import org.wso2.carbon.identity.core.SAMLSSOServiceProviderManager; @@ -77,9 +79,9 @@ import org.wso2.carbon.identity.oauth2.token.bindings.impl.SSOSessionBasedTokenBinder; import org.wso2.carbon.identity.oauth2.token.handlers.claims.JWTAccessTokenClaimProvider; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.NoPolicyPolicyHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.RoleBasedPolicyHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.NoPolicyScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.RoleBasedScopeValidationHandler; import org.wso2.carbon.identity.oauth2.validators.scope.RoleBasedScopeIssuer; import org.wso2.carbon.identity.oauth2.validators.scope.ScopeValidator; import org.wso2.carbon.identity.openidconnect.OpenIDConnectClaimFilter; @@ -90,6 +92,7 @@ import org.wso2.carbon.identity.organization.management.service.OrganizationManagementInitialize; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; import org.wso2.carbon.identity.organization.management.service.OrganizationUserResidentResolverService; +import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService; import org.wso2.carbon.identity.user.store.configuration.listener.UserStoreConfigListener; import org.wso2.carbon.idp.mgt.IdpManager; import org.wso2.carbon.registry.core.service.RegistryService; @@ -334,8 +337,8 @@ protected void activate(ComponentContext context) { bundleContext.registerService(OAuth2ScopeService.class.getName(), oAuth2ScopeService, null); // Registering OAuth2ScopeService under ScopeService interface as the default service. bundleContext.registerService(ScopeMetadataService.class, oAuth2ScopeService, null); - bundleContext.registerService(ScopeValidatorPolicyHandler.class, new RoleBasedPolicyHandler(), null); - bundleContext.registerService(ScopeValidatorPolicyHandler.class, new NoPolicyPolicyHandler(), null); + bundleContext.registerService(ScopeValidationHandler.class, new RoleBasedScopeValidationHandler(), null); + bundleContext.registerService(ScopeValidationHandler.class, new NoPolicyScopeValidationHandler(), null); // Note : DO NOT add any activation related code below this point, // to make sure the server doesn't start up if any activation failures occur @@ -1193,4 +1196,63 @@ protected void unsetRealmService(RealmService realmService) { OAuth2ServiceComponentHolder.getInstance().setRealmService(null); } + + @Reference( + name = "identity.authorized.api.management.component", + service = AuthorizedAPIManagementService.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetAuthorizedAPIManagementService" + ) + protected void setAuthorizedAPIManagementService(AuthorizedAPIManagementService authorizedAPIManagementService) { + + OAuth2ServiceComponentHolder.getInstance() + .setAuthorizedAPIManagementService(authorizedAPIManagementService); + } + + protected void unsetAuthorizedAPIManagementService(AuthorizedAPIManagementService authorizedAPIManagementService) { + + OAuth2ServiceComponentHolder.getInstance().setAuthorizedAPIManagementService(null); + } + + @Reference( + name = "api.resource.mgt.service.component", + service = APIResourceManager.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetAPIResourceManagerService" + ) + protected void setAPIResourceManagerService(APIResourceManager apiResourceManager) { + OAuth2ServiceComponentHolder.getInstance().setApiResourceManager(apiResourceManager); + } + protected void unsetAPIResourceManagerService(APIResourceManager apiResourceManager) { + OAuth2ServiceComponentHolder.getInstance().setApiResourceManager(null); + } + + /** + * Set role management service V2 implementation. + * + * @param roleManagementService RoleManagementServiceV2. + */ + @Reference( + name = "org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService", + service = org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetRoleManagementServiceV2") + protected void setRoleManagementServiceV2(RoleManagementService roleManagementService) { + + OAuth2ServiceComponentHolder.getInstance().setRoleManagementServiceV2(roleManagementService); + } + + /** + * Unset role management service V2 implementation. + * + * @param roleManagementService RoleManagementServiceV2 + */ + protected void unsetRoleManagementServiceV2(RoleManagementService roleManagementService) { + + OAuth2ServiceComponentHolder.getInstance().setRoleManagementServiceV2(null); + } + } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java index 6134484271e..13dd877a98d 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java @@ -18,10 +18,12 @@ package org.wso2.carbon.identity.oauth2.internal; +import org.wso2.carbon.identity.api.resource.mgt.APIResourceManager; import org.wso2.carbon.identity.application.authentication.framework.AuthenticationDataPublisher; import org.wso2.carbon.identity.application.authentication.framework.AuthenticationMethodNameTranslator; import org.wso2.carbon.identity.application.authentication.framework.UserSessionManagementService; import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; +import org.wso2.carbon.identity.application.mgt.AuthorizedAPIManagementService; import org.wso2.carbon.identity.consent.server.configs.mgt.services.ConsentServerConfigsManagementService; import org.wso2.carbon.identity.core.SAMLSSOServiceProviderManager; import org.wso2.carbon.identity.core.handler.HandlerComparator; @@ -46,6 +48,7 @@ import org.wso2.carbon.identity.organization.management.service.OrganizationManagementInitialize; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; import org.wso2.carbon.identity.organization.management.service.OrganizationUserResidentResolverService; +import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService; import org.wso2.carbon.idp.mgt.IdpManager; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.user.core.service.RealmService; @@ -102,6 +105,10 @@ public class OAuth2ServiceComponentHolder { private RefreshTokenGrantProcessor refreshTokenGrantProcessor; private OAuth2RevocationProcessor revocationProcessor; + private AuthorizedAPIManagementService authorizedAPIManagementService; + private APIResourceManager apiResourceManager; + private RoleManagementService roleManagementServiceV2; + private OAuth2ServiceComponentHolder() { } @@ -712,4 +719,51 @@ public void removeAuthorizationRequestBuilder(OAuthAuthorizationRequestBuilder o oAuthAuthorizationRequestBuilders.remove(oAuthAuthorizationRequestBuilder); } + + public AuthorizedAPIManagementService getAuthorizedAPIManagementService() { + + return authorizedAPIManagementService; + } + + public void setAuthorizedAPIManagementService(AuthorizedAPIManagementService authorizedAPIManagementService) { + + this.authorizedAPIManagementService = authorizedAPIManagementService; + } + + /** + * Get APIResourceManager osgi service. + * + * @return APIResourceManager. + */ + public APIResourceManager getApiResourceManager() { + return apiResourceManager; + } + /** + * Set APIResourceManager osgi service. + * + * @param apiResourceManager APIResourceManager. + */ + public void setApiResourceManager(APIResourceManager apiResourceManager) { + this.apiResourceManager = apiResourceManager; + } + + /** + * Get {@link RoleManagementService}. + * + * @return Instance of {@link RoleManagementService}. + */ + public RoleManagementService getRoleManagementServiceV2() { + + return roleManagementServiceV2; + } + + /** + * Set {@link RoleManagementService}. + * + * @param roleManagementServiceV2 Instance of {@link RoleManagementService}. + */ + public void setRoleManagementServiceV2(RoleManagementService roleManagementServiceV2) { + + this.roleManagementServiceV2 = roleManagementServiceV2; + } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index c48b0163432..7744bc14496 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -4,8 +4,11 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.api.resource.mgt.APIResourceMgtException; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException; +import org.wso2.carbon.identity.application.common.model.AuthorizedScopes; +import org.wso2.carbon.identity.application.common.model.Scope; import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; import org.wso2.carbon.identity.oauth.IdentityOAuthAdminException; import org.wso2.carbon.identity.oauth.OAuthAdminServiceImpl; @@ -14,9 +17,9 @@ import org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.PolicyContext; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandlerException; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationContext; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandlerException; import java.util.ArrayList; import java.util.Arrays; @@ -53,7 +56,7 @@ public List validateScope(OAuthAuthzReqMessageContext authzReqMessageCon String clientId = authzReqMessageContext.getAuthorizationReqDTO().getConsumerKey(); String appId = getApplicationId(clientId, tenantDomain); return getAuthorizedScopes(requestedScopes, authzReqMessageContext.getAuthorizationReqDTO().getUser(), appId, - tenantDomain); + null, tenantDomain); } public List validateScope(OAuthTokenReqMessageContext tokenReqMessageContext) @@ -69,11 +72,13 @@ public List validateScope(OAuthTokenReqMessageContext tokenReqMessageCon String tenantDomain = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getTenantDomain(); String clientId = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getClientId(); String appId = getApplicationId(clientId, tenantDomain); - return getAuthorizedScopes(requestedScopes, tokenReqMessageContext.getAuthorizedUser(), appId, tenantDomain); + String grantType = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getGrantType(); + return getAuthorizedScopes(requestedScopes, tokenReqMessageContext.getAuthorizedUser(), appId, grantType, + tenantDomain); } private List getAuthorizedScopes(List requestedScopes, AuthenticatedUser authenticatedUser, - String appId, String tenantDomain) throws IdentityOAuth2Exception { + String appId, String grantType, String tenantDomain) throws IdentityOAuth2Exception { // Filter OIDC scopes and add to approved scopes list. if (LOG.isDebugEnabled()) { @@ -89,36 +94,31 @@ private List getAuthorizedScopes(List requestedScopes, Authentic List approvedScopes = new ArrayList<>(requestedOIDCScopes); requestedScopes = removeOIDCScopes(requestedScopes, requestedOIDCScopes); if (requestedScopes.contains(SYSTEM_SCOPE)) { - // TODO : get all internal scopes - List allInternalScopes = new ArrayList<>(); - requestedScopes.addAll(allInternalScopes); - } - Map> policies = getAuthorizedScopes(appId, tenantDomain); - if (policies == null) { - return new ArrayList<>(); + requestedScopes.addAll(getInternalScopes(tenantDomain)); } - List scopeValidatorPolicyHandlers = + List authorizedScopesList = getAuthorizedScopes(appId, tenantDomain); + List scopeValidationHandlers = OAuthComponentServiceHolder.getInstance().getScopeValidatorPolicyHandlers(); Map> validatedScopesByHandler = new HashMap<>(); - for (Map.Entry> entry : policies.entrySet()) { - String policyId = entry.getKey(); - List authorizedScopes = entry.getValue(); - - for (ScopeValidatorPolicyHandler scopeValidatorPolicyHandler : scopeValidatorPolicyHandlers) { - if (scopeValidatorPolicyHandler.canHandle(policyId)) { - PolicyContext policyContext = new PolicyContext(); - policyContext.setAuthenticatedUser(authenticatedUser); - policyContext.setAppId(appId); + for (AuthorizedScopes authorizedScopes: authorizedScopesList) { + String policyId = authorizedScopes.getPolicyId(); + ScopeValidationContext policyContext = new ScopeValidationContext(); + policyContext.setAuthenticatedUser(authenticatedUser); + policyContext.setAppId(appId); + policyContext.setPolicyId(policyId); + policyContext.setGrantType(grantType); + for (ScopeValidationHandler scopeValidationHandler : scopeValidationHandlers) { + if (scopeValidationHandler.canHandle(policyContext)) { policyContext.setValidatedScopesByHandler(validatedScopesByHandler); List validatedScopes; try { - validatedScopes = scopeValidatorPolicyHandler.validateScopes(authorizedScopes, + validatedScopes = scopeValidationHandler.validateScopes(authorizedScopes.getScopes(), requestedScopes, policyContext); - } catch (ScopeValidatorPolicyHandlerException e) { + } catch (ScopeValidationHandlerException e) { throw new IdentityOAuth2Exception("Error while validating policies roles from " + "authorization service.", e); } - validatedScopesByHandler.put(scopeValidatorPolicyHandler.getName(), validatedScopes); + validatedScopesByHandler.put(scopeValidationHandler.getName(), validatedScopes); } } } @@ -144,16 +144,28 @@ private List getAuthorizedScopes(List requestedScopes, Authentic return approvedScopes; } - private Map> getAuthorizedScopes(String appId, String tenantDomain) { + private List getAuthorizedScopes(String appId, String tenantDomain) + throws IdentityOAuth2Exception { - // TODO : get authorized scopes - Map> authorizedScopes = new HashMap<>(); - List scopes = new ArrayList<>(); - scopes.add("scope1"); - scopes.add("scope2"); - authorizedScopes.put("NoPolicy", scopes); - authorizedScopes.put("RBAC", scopes); - return authorizedScopes; + try { + return OAuth2ServiceComponentHolder.getInstance() + .getAuthorizedAPIManagementService().getAuthorizedScopes(appId, tenantDomain); + } catch (IdentityApplicationManagementException e) { + throw new IdentityOAuth2Exception("Error while retrieving authorized scopes for app : " + appId + + "tenant domain : " + tenantDomain, e); + } + } + + private List getInternalScopes(String tenantDomain) throws IdentityOAuth2Exception { + + try { + List scopes = OAuth2ServiceComponentHolder.getInstance() + .getApiResourceManager().getScopesByTenantDomain(tenantDomain, "name sw internal_"); + return scopes.stream().map(Scope::getName).collect(Collectors.toCollection(ArrayList::new)); + } catch (APIResourceMgtException e) { + throw new IdentityOAuth2Exception("Error while retrieving internal scopes for tenant domain : " + + tenantDomain, e); + } } private Set getRequestedOIDCScopes(String tenantDomain, List requestedScopes) @@ -164,7 +176,8 @@ private Set getRequestedOIDCScopes(String tenantDomain, List req List oidcScopes = oAuthAdminServiceImpl.getRegisteredOIDCScope(tenantDomain); return requestedScopes.stream().distinct().filter(oidcScopes::contains).collect(Collectors.toSet()); } catch (IdentityOAuthAdminException e) { - throw new RuntimeException(e); + throw new IdentityOAuth2Exception("Error while retrieving oidc scopes for tenant domain : " + + tenantDomain, e); } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationContext.java similarity index 71% rename from components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java rename to components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationContext.java index 7a17bc2fdc6..5aede81f56b 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/PolicyContext.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationContext.java @@ -8,10 +8,13 @@ /** * PolicyContext */ -public class PolicyContext { +public class ScopeValidationContext { private AuthenticatedUser authenticatedUser; private String appId; + private String grantType; + + private String policyId; private Map> validatedScopesByHandler; public AuthenticatedUser getAuthenticatedUser() { @@ -43,4 +46,24 @@ public void setValidatedScopesByHandler(Map> validatedScope this.validatedScopesByHandler = validatedScopesByHandler; } + + public String getGrantType() { + + return grantType; + } + + public void setGrantType(String grantType) { + + this.grantType = grantType; + } + + public String getPolicyId() { + + return policyId; + } + + public void setPolicyId(String policyId) { + + this.policyId = policyId; + } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java new file mode 100644 index 00000000000..71fc75988aa --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java @@ -0,0 +1,17 @@ +package org.wso2.carbon.identity.oauth2.validators.policyhandler; + +import java.util.List; + +/** + * ScopeValidatorPolicyHandler + */ +public interface ScopeValidationHandler { + + boolean canHandle(ScopeValidationContext scopeValidationContext); + List validateScopes(List requestedScopes, List appAuthorizedScopes, + ScopeValidationContext scopeValidationContext) throws ScopeValidationHandlerException; + String getPolicyID(); + + String getName(); + +} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandlerException.java similarity index 68% rename from components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java rename to components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandlerException.java index 5e8f45de74b..9566b69e3f4 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandlerException.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandlerException.java @@ -3,14 +3,14 @@ /** * ScopeValidatorPolicyHandlerException */ -public class ScopeValidatorPolicyHandlerException extends Exception { +public class ScopeValidationHandlerException extends Exception { /** * Constructs a new exception with an error message. * * @param message The detail message. */ - public ScopeValidatorPolicyHandlerException(String message) { + public ScopeValidationHandlerException(String message) { super(message); } @@ -21,7 +21,7 @@ public ScopeValidatorPolicyHandlerException(String message) { * @param message The detail message. * @param cause The cause. */ - public ScopeValidatorPolicyHandlerException(String message, Throwable cause) { + public ScopeValidationHandlerException(String message, Throwable cause) { super(message, cause); } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java deleted file mode 100644 index 2bfc894b062..00000000000 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidatorPolicyHandler.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.wso2.carbon.identity.oauth2.validators.policyhandler; - -import java.util.List; - -/** - * ScopeValidatorPolicyHandler - */ -public interface ScopeValidatorPolicyHandler { - - boolean canHandle(String policyId); - List validateScopes(List requestedScopes, List policyAuthorizedScopes, - PolicyContext policyContext) throws ScopeValidatorPolicyHandlerException; - String getPolicyID(); - - String getName(); - -} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java new file mode 100644 index 00000000000..1542c30841f --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java @@ -0,0 +1,39 @@ +package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; + +import org.wso2.carbon.identity.oauth.common.OAuthConstants; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationContext; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandlerException; + +import java.util.List; +import java.util.stream.Collectors; + +public class M2MScopeValidationHandler implements ScopeValidationHandler { + + @Override + public boolean canHandle(ScopeValidationContext scopeValidationContext) { + + return OAuthConstants.GrantTypes.CLIENT_CREDENTIALS.equals(scopeValidationContext.getGrantType()) && + !getPolicyID().equals("NoPolicy"); + } + + @Override + public List validateScopes(List requestedScopes, List appAuthorizedScopes, + ScopeValidationContext scopeValidationContext) + throws ScopeValidationHandlerException { + + return requestedScopes.stream().filter(appAuthorizedScopes::contains).collect(Collectors.toList()); + } + + @Override + public String getPolicyID() { + + return null; + } + + @Override + public String getName() { + + return "M2MScopeValidationHandler"; + } +} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java deleted file mode 100644 index c5bfe99efd9..00000000000 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyPolicyHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; - -import org.wso2.carbon.identity.oauth2.validators.policyhandler.PolicyContext; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandlerException; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * NoPolicyPolicyHandler - */ -public class NoPolicyPolicyHandler implements ScopeValidatorPolicyHandler { - - @Override - public boolean canHandle(String policyId) { - - return getPolicyID().equals(policyId); - } - - @Override - public List validateScopes(List requestedScopes, List policyAuthorizedScopes, - PolicyContext policyContext) throws ScopeValidatorPolicyHandlerException { - - return requestedScopes.stream().filter(policyAuthorizedScopes::contains).collect(Collectors.toList()); - } - - @Override - public String getPolicyID() { - - return "NoPolicy"; - } - - @Override - public String getName() { - - return "NoPolicyPolicyHandler"; - } -} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java new file mode 100644 index 00000000000..0eb08cc0ea7 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java @@ -0,0 +1,41 @@ +package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; + +import org.wso2.carbon.identity.oauth.common.OAuthConstants; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationContext; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandlerException; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * NoPolicyPolicyHandler + */ +public class NoPolicyScopeValidationHandler implements ScopeValidationHandler { + + @Override + public boolean canHandle(ScopeValidationContext scopeValidationContext) { + + return getPolicyID().equals(scopeValidationContext.getPolicyId()); + } + + @Override + public List validateScopes(List requestedScopes, List appAuthorizedScopes, + ScopeValidationContext scopeValidationContext) + throws ScopeValidationHandlerException { + + return requestedScopes.stream().filter(appAuthorizedScopes::contains).collect(Collectors.toList()); + } + + @Override + public String getPolicyID() { + + return "NoPolicy"; + } + + @Override + public String getName() { + + return "NoPolicyScopeValidationHandler"; + } +} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java deleted file mode 100644 index e47016a8b9b..00000000000 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedPolicyHandler.java +++ /dev/null @@ -1,146 +0,0 @@ -package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; -import org.wso2.carbon.identity.oauth2.util.OAuth2Util; -import org.wso2.carbon.identity.oauth2.validators.DefaultOAuth2ScopeValidator; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.PolicyContext; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidatorPolicyHandlerException; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.api.UserStoreManager; -import org.wso2.carbon.user.core.NotImplementedException; -import org.wso2.carbon.user.core.common.AbstractUserStoreManager; -import org.wso2.carbon.user.core.common.Group; -import org.wso2.carbon.user.core.service.RealmService; -import org.wso2.carbon.user.core.util.UserCoreUtil; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -/** - * RoleBasedPolicyHandler - */ -public class RoleBasedPolicyHandler implements ScopeValidatorPolicyHandler { - - private static final Log LOG = LogFactory.getLog(DefaultOAuth2ScopeValidator.class); - - @Override - public boolean canHandle(String policyId) { - - return getPolicyID().equals(policyId); - } - - @Override - public List validateScopes(List requestedScopes, List policyAuthorizedScopes, - PolicyContext policyContext) throws ScopeValidatorPolicyHandlerException { - - List userRoles = getUserRoles(policyContext.getAuthenticatedUser(), policyContext.getAppId()); - List associatedScopes = getAssociatedScopesForRoles(userRoles, - policyContext.getAuthenticatedUser().getTenantDomain()); - List filteredScopes = policyAuthorizedScopes.stream().filter(associatedScopes::contains) - .collect(Collectors.toList()); - return requestedScopes.stream().filter(filteredScopes::contains).collect(Collectors.toList()); - } - - private List getAssociatedScopesForRoles(List roles, String tenantDomain) { - - // TODO : - return null; - } - - private List getUserRoles(AuthenticatedUser authenticatedUser, String appId) { - - // TODO : Get hybrid user roles of the user - - // TODO: Get groups of the user - List groups; - try { - groups = getUserGroups(authenticatedUser); - } catch (IdentityOAuth2Exception e) { - throw new RuntimeException(e); - } - // TODO: Get roles of the groups - - // TODO : Filter roles by app - - return null; - } - - /** - * Get the groups of the authenticated user. - * - * @param authenticatedUser Authenticated user. - * @return - Groups of the user. - */ - private List getUserGroups(AuthenticatedUser authenticatedUser) - throws IdentityOAuth2Exception { - - if (LOG.isDebugEnabled()) { - LOG.debug("Started group fetching for scope validation."); - } - List userGroups = new ArrayList<>(); - if (authenticatedUser.isFederatedUser()) { - // TODO: get federated user groups | at the moment, if the user is a federated user we skip the validation - return userGroups; - } - RealmService realmService = UserCoreUtil.getRealmService(); - try { - int tenantId = OAuth2Util.getTenantId(authenticatedUser.getTenantDomain()); - UserStoreManager userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager(); - List groups = - ((AbstractUserStoreManager) userStoreManager).getGroupListOfUser(authenticatedUser.getUserId(), - null, null); - // Exclude internal and application groups from the list. - for (Group group : groups) { - userGroups.add(group.getGroupName()); - } - } catch (UserIdNotFoundException e) { - throw new IdentityOAuth2Exception(e.getMessage(), e); - } catch (UserStoreException e) { - if (isDoGetGroupListOfUserNotImplemented(e)) { - return userGroups; - } - throw new IdentityOAuth2Exception(e.getMessage(), e); - } - if (LOG.isDebugEnabled()) { - LOG.debug("Completed group fetching for scope validation."); - } - return userGroups; - } - - /** - * Check if the UserStoreException occurred due to the doGetGroupListOfUser method not being implemented. - * - * @param e UserStoreException. - * @return true if the UserStoreException was caused by the doGetGroupListOfUser method not being implemented, - * false otherwise. - */ - private boolean isDoGetGroupListOfUserNotImplemented(UserStoreException e) { - - Throwable cause = e.getCause(); - while (cause != null) { - if (cause instanceof NotImplementedException) { - return true; - } - cause = cause.getCause(); - } - return false; - } - - @Override - public String getPolicyID() { - - return "RBAC"; - } - - @Override - public String getName() { - - return "RoleBasedPolicyHandler"; - } -} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java new file mode 100644 index 00000000000..f7940e8f708 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java @@ -0,0 +1,301 @@ +package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; +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; +import org.wso2.carbon.identity.application.common.model.IdPGroup; +import org.wso2.carbon.identity.application.common.model.IdentityProvider; +import org.wso2.carbon.identity.application.common.model.RoleV2; +import org.wso2.carbon.identity.application.common.model.Scope; +import org.wso2.carbon.identity.oauth.common.OAuthConstants; +import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; +import org.wso2.carbon.identity.oauth2.util.OAuth2Util; +import org.wso2.carbon.identity.oauth2.validators.DefaultOAuth2ScopeValidator; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationContext; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandlerException; +import org.wso2.carbon.identity.role.v2.mgt.core.IdentityRoleManagementException; +import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; +import org.wso2.carbon.user.core.NotImplementedException; +import org.wso2.carbon.user.core.common.AbstractUserStoreManager; +import org.wso2.carbon.user.core.common.Group; +import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.user.core.util.UserCoreUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * RoleBasedScopeValidationHandler + */ +public class RoleBasedScopeValidationHandler implements ScopeValidationHandler { + + private static final Log LOG = LogFactory.getLog(DefaultOAuth2ScopeValidator.class); + + @Override + public boolean canHandle(ScopeValidationContext scopeValidationContext) { + + return getPolicyID().equals(scopeValidationContext.getPolicyId()) + && !OAuthConstants.GrantTypes.CLIENT_CREDENTIALS.equals(scopeValidationContext.getGrantType()); + } + + @Override + public List validateScopes(List requestedScopes, List appAuthorizedScopes, + ScopeValidationContext scopeValidationContext) + throws ScopeValidationHandlerException { + + List userRoles = getUserRoles(scopeValidationContext.getAuthenticatedUser(), + scopeValidationContext.getAppId()); + List associatedScopes = getAssociatedScopesForRoles(userRoles, + scopeValidationContext.getAuthenticatedUser().getTenantDomain()); + List filteredScopes = appAuthorizedScopes.stream().filter(associatedScopes::contains) + .collect(Collectors.toList()); + return requestedScopes.stream().filter(filteredScopes::contains).collect(Collectors.toList()); + } + + private List getAssociatedScopesForRoles(List roles, String tenantDomain) + throws ScopeValidationHandlerException { + + try { + return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() + .getPermissionListOfRoles(roles, tenantDomain); + } catch (IdentityRoleManagementException e) { + throw new ScopeValidationHandlerException("Error while retrieving scope list of roles : " + + StringUtils.join(roles, ",") + "tenant domain : " + tenantDomain, e); + } + } + + private List getUserRoles(AuthenticatedUser authenticatedUser, String appId) + throws ScopeValidationHandlerException { + + // Get role id list of the user. + List roleIdsOfUser;; + try { + roleIdsOfUser = getRoleIdsOfUser(authenticatedUser.getUserId(), authenticatedUser.getTenantDomain()); + } catch (UserIdNotFoundException e) { + throw new ScopeValidationHandlerException("Error while resolving user id of user", e); + } + // Get groups of the user. + List groups = getUserGroups(authenticatedUser); + List roleIdsOfGroups = null; + if (groups.isEmpty()) { + roleIdsOfGroups = getRoleIdsOfGroups(groups, authenticatedUser.getTenantDomain()); + } + List roleIdsOfIdGroups = null; + if (authenticatedUser.isFederatedUser()) { + roleIdsOfIdGroups = getRoleIdsOfIdpGroups(getUserIdpGroups(authenticatedUser), authenticatedUser.getTenantDomain()); + } + List roleIds = null; + if (roleIdsOfUser != null && roleIdsOfGroups != null && roleIdsOfIdGroups != null) { + roleIds = Stream.concat(Stream.concat(roleIdsOfUser.stream(), roleIdsOfGroups.stream()), roleIdsOfIdGroups.stream()) + .collect(Collectors.toList()); + } + if (roleIds != null && !roleIds.isEmpty()) { + return getFilteredRoleIds(roleIds, appId, authenticatedUser.getTenantDomain()); + } + return new ArrayList<>(); + } + + private List getFilteredRoleIds(List roleId, String appId, String tenantDomain) + throws ScopeValidationHandlerException { + + List rolesAssociatedWithApp = getRoleIdsAssociatedWithApp(appId, tenantDomain); + return roleId.stream().distinct().filter(rolesAssociatedWithApp::contains).collect(Collectors.toList()); + } + + private List getRoleIdsAssociatedWithApp(String appId, String tenantDomain) + throws ScopeValidationHandlerException { + + try { + return OAuth2ServiceComponentHolder.getApplicationMgtService() + .getAssociatedRolesOfApplication(appId, tenantDomain).stream().map(RoleV2::getName) + .collect(Collectors.toCollection(ArrayList::new)); + } catch (IdentityApplicationManagementException e) { + throw new ScopeValidationHandlerException("Error while retrieving role id list of app : " + appId + + "tenant domain : " + tenantDomain, e); + } + } + + private List getRoleIdsOfUser(String userId, String tenantDomain) throws ScopeValidationHandlerException { + + try { + return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() + .getRoleIdListOfUser(userId, tenantDomain); + } catch (IdentityRoleManagementException e) { + throw new ScopeValidationHandlerException("Error while retrieving role id list of user : " + userId + + "tenant domain : " + tenantDomain, e); + } + } + + private List getRoleIdsOfGroups(List groups, String tenantDomain) throws ScopeValidationHandlerException { + + try { + return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() + .getRoleIdListOfGroups(groups, tenantDomain); + } catch (IdentityRoleManagementException e) { + throw new ScopeValidationHandlerException("Error while retrieving role id list of groups : " + + StringUtils.join(groups, ",") + "tenant domain : " + tenantDomain, e); + } + } + + private List getRoleIdsOfIdpGroups(List groups, String tenantDomain) throws ScopeValidationHandlerException { + + try { + return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() + .getRoleIdListOfIdpGroups(groups, tenantDomain); + } catch (IdentityRoleManagementException e) { + throw new ScopeValidationHandlerException("Error while retrieving role id list of groups : " + + StringUtils.join(groups, ",") + "tenant domain : " + tenantDomain, e); + } + } + + /** + * Get the groups of the authenticated user. + * + * @param authenticatedUser Authenticated user. + * @return - Groups of the user. + */ + private List getUserGroups(AuthenticatedUser authenticatedUser) + throws ScopeValidationHandlerException { + + if (LOG.isDebugEnabled()) { + LOG.debug("Started group fetching for scope validation."); + } + List userGroups = new ArrayList<>(); + RealmService realmService = UserCoreUtil.getRealmService(); + try { + int tenantId = OAuth2Util.getTenantId(authenticatedUser.getTenantDomain()); + UserStoreManager userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager(); + List groups = + ((AbstractUserStoreManager) userStoreManager).getGroupListOfUser(authenticatedUser.getUserId(), + null, null); + for (Group group : groups) { + userGroups.add(group.getGroupName()); + } + } catch (UserIdNotFoundException | IdentityOAuth2Exception e) { + throw new ScopeValidationHandlerException(e.getMessage(), e); + } catch (UserStoreException e) { + if (isDoGetGroupListOfUserNotImplemented(e)) { + return userGroups; + } + throw new ScopeValidationHandlerException(e.getMessage(), e); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Completed group fetching for scope validation."); + } + return userGroups; + } + + /** + * Get the groups of the authenticated user. + * + * @param authenticatedUser Authenticated user. + * @return - Groups of the user. + */ + private List getUserIdpGroups(AuthenticatedUser authenticatedUser) + throws ScopeValidationHandlerException { + + if (LOG.isDebugEnabled()) { + LOG.debug("Started group fetching for scope validation."); + } + String idpName = authenticatedUser.getFederatedIdPName(); + String tenantDomain = authenticatedUser.getTenantDomain(); + IdentityProvider federatedIdP = getIdentityProvider(idpName, tenantDomain); + List idpGroups = new ArrayList<>(Arrays.asList(federatedIdP.getIdPGroupConfig())); + // Convert idPGroups into a map for quick lookup + Map groupNameToIdMap = new HashMap<>(); + for (IdPGroup group : idpGroups) { + groupNameToIdMap.put(group.getIdpGroupName(), group.getIdpGroupId()); + } + if (federatedIdP != null) { + String idpGroupsClaimUri = Arrays.stream(federatedIdP.getClaimConfig().getClaimMappings()) + .filter(claimMapping -> claimMapping.getLocalClaim().getClaimUri() + .equals(FrameworkConstants.GROUPS_CLAIM)) + .map(claimMapping -> claimMapping.getRemoteClaim().getClaimUri()) + .findFirst() + .orElse(null); + // If there is no group claim mapping, no need to proceed. + if (idpGroupsClaimUri == null) { + return new ArrayList<>(); + } + Map userAttributes = authenticatedUser.getUserAttributes(); + for (Map.Entry entry : userAttributes.entrySet()) { + ClaimMapping claimMapping = entry.getKey(); + if (idpGroupsClaimUri.equals(claimMapping.getRemoteClaim().getClaimUri())) { + String idPGroupsClaim = entry.getValue(); + if (StringUtils.isNotBlank(idPGroupsClaim)) { + List groupNames = new ArrayList<>(Arrays.asList(idPGroupsClaim + .split(Pattern.quote(FrameworkUtils.getMultiAttributeSeparator())))); + return groupNames.stream().map(groupNameToIdMap::get).collect(Collectors.toList()); + } + } + } + } + return new ArrayList<>(); + } + + /** + * Get the Identity Provider object for the given identity provider name. + * + * @param idpName Identity provider name. + * @param tenantDomain Tenant domain. + * @return Identity Provider object. + * @throws ScopeValidationHandlerException Exception thrown when getting the identity provider. + */ + private IdentityProvider getIdentityProvider(String idpName, String tenantDomain) + throws ScopeValidationHandlerException { + + try { + return OAuth2ServiceComponentHolder.getInstance().getIdpManager().getIdPByName(idpName, tenantDomain); + } catch (IdentityProviderManagementException e) { + throw new ScopeValidationHandlerException("Error while retrieving idp by idp name : " + idpName, e); + } + } + + + /** + * Check if the UserStoreException occurred due to the doGetGroupListOfUser method not being implemented. + * + * @param e UserStoreException. + * @return true if the UserStoreException was caused by the doGetGroupListOfUser method not being implemented, + * false otherwise. + */ + private boolean isDoGetGroupListOfUserNotImplemented(UserStoreException e) { + + Throwable cause = e.getCause(); + while (cause != null) { + if (cause instanceof NotImplementedException) { + return true; + } + cause = cause.getCause(); + } + return false; + } + + @Override + public String getPolicyID() { + + return "RBAC"; + } + + @Override + public String getName() { + + return "RoleBasedScopeValidationHandler"; + } +} diff --git a/pom.xml b/pom.xml index f88d6d3160e..7dd53c379be 100644 --- a/pom.xml +++ b/pom.xml @@ -685,7 +685,16 @@ test - + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.api.resource.mgt + ${carbon.identity.framework.version} + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.role.v2.mgt.core + ${carbon.identity.framework.version} + @@ -863,7 +872,7 @@ [1.0.1, 2.0.0) - 5.25.358 + 5.25.403-SNAPSHOT [5.25.234, 7.0.0) From 0441a4793b49ea1a4c61a967da861ccc08e1001b Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Thu, 19 Oct 2023 14:49:47 +0530 Subject: [PATCH 06/29] implement rbac --- .../oauth2/internal/OAuth2ServiceComponent.java | 2 ++ .../validators/DefaultOAuth2ScopeValidator.java | 3 ++- .../impl/M2MScopeValidationHandler.java | 3 +++ .../impl/NoPolicyScopeValidationHandler.java | 1 - .../impl/RoleBasedScopeValidationHandler.java | 13 ++++++++----- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java index 7d3f05672d4..31af2fff71e 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java @@ -80,6 +80,7 @@ import org.wso2.carbon.identity.oauth2.token.handlers.claims.JWTAccessTokenClaimProvider; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.M2MScopeValidationHandler; import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.NoPolicyScopeValidationHandler; import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.RoleBasedScopeValidationHandler; import org.wso2.carbon.identity.oauth2.validators.scope.RoleBasedScopeIssuer; @@ -339,6 +340,7 @@ protected void activate(ComponentContext context) { bundleContext.registerService(ScopeMetadataService.class, oAuth2ScopeService, null); bundleContext.registerService(ScopeValidationHandler.class, new RoleBasedScopeValidationHandler(), null); bundleContext.registerService(ScopeValidationHandler.class, new NoPolicyScopeValidationHandler(), null); + bundleContext.registerService(ScopeValidationHandler.class, new M2MScopeValidationHandler(), null); // Note : DO NOT add any activation related code below this point, // to make sure the server doesn't start up if any activation failures occur diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index 7744bc14496..9339f99632c 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -78,7 +78,8 @@ public List validateScope(OAuthTokenReqMessageContext tokenReqMessageCon } private List getAuthorizedScopes(List requestedScopes, AuthenticatedUser authenticatedUser, - String appId, String grantType, String tenantDomain) throws IdentityOAuth2Exception { + String appId, String grantType, String tenantDomain) + throws IdentityOAuth2Exception { // Filter OIDC scopes and add to approved scopes list. if (LOG.isDebugEnabled()) { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java index 1542c30841f..becac24de43 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java @@ -8,6 +8,9 @@ import java.util.List; import java.util.stream.Collectors; +/** + * M2MScopeValidationHandler + */ public class M2MScopeValidationHandler implements ScopeValidationHandler { @Override diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java index 0eb08cc0ea7..b951c08e593 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java @@ -1,6 +1,5 @@ package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; -import org.wso2.carbon.identity.oauth.common.OAuthConstants; import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationContext; import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandlerException; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java index f7940e8f708..4156d1f9abf 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java @@ -12,7 +12,6 @@ import org.wso2.carbon.identity.application.common.model.IdPGroup; import org.wso2.carbon.identity.application.common.model.IdentityProvider; import org.wso2.carbon.identity.application.common.model.RoleV2; -import org.wso2.carbon.identity.application.common.model.Scope; import org.wso2.carbon.identity.oauth.common.OAuthConstants; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; @@ -98,11 +97,13 @@ private List getUserRoles(AuthenticatedUser authenticatedUser, String ap } List roleIdsOfIdGroups = null; if (authenticatedUser.isFederatedUser()) { - roleIdsOfIdGroups = getRoleIdsOfIdpGroups(getUserIdpGroups(authenticatedUser), authenticatedUser.getTenantDomain()); + roleIdsOfIdGroups = getRoleIdsOfIdpGroups(getUserIdpGroups(authenticatedUser), + authenticatedUser.getTenantDomain()); } List roleIds = null; if (roleIdsOfUser != null && roleIdsOfGroups != null && roleIdsOfIdGroups != null) { - roleIds = Stream.concat(Stream.concat(roleIdsOfUser.stream(), roleIdsOfGroups.stream()), roleIdsOfIdGroups.stream()) + roleIds = Stream.concat(Stream.concat(roleIdsOfUser.stream(), roleIdsOfGroups.stream()), + roleIdsOfIdGroups.stream()) .collect(Collectors.toList()); } if (roleIds != null && !roleIds.isEmpty()) { @@ -142,7 +143,8 @@ private List getRoleIdsOfUser(String userId, String tenantDomain) throws } } - private List getRoleIdsOfGroups(List groups, String tenantDomain) throws ScopeValidationHandlerException { + private List getRoleIdsOfGroups(List groups, String tenantDomain) + throws ScopeValidationHandlerException { try { return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() @@ -153,7 +155,8 @@ private List getRoleIdsOfGroups(List groups, String tenantDomain } } - private List getRoleIdsOfIdpGroups(List groups, String tenantDomain) throws ScopeValidationHandlerException { + private List getRoleIdsOfIdpGroups(List groups, String tenantDomain) + throws ScopeValidationHandlerException { try { return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() From 583257412d788c258c1dc1120191a4fe504926f0 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Thu, 19 Oct 2023 18:13:50 +0530 Subject: [PATCH 07/29] fix get user group and role ids list --- .../impl/RoleBasedScopeValidationHandler.java | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java index 4156d1f9abf..538d5cf4a15 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java @@ -39,6 +39,9 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import static org.wso2.carbon.user.core.UserCoreConstants.APPLICATION_DOMAIN; +import static org.wso2.carbon.user.core.UserCoreConstants.INTERNAL_DOMAIN; + /** * RoleBasedScopeValidationHandler */ @@ -82,31 +85,33 @@ private List getAssociatedScopesForRoles(List roles, String tena private List getUserRoles(AuthenticatedUser authenticatedUser, String appId) throws ScopeValidationHandlerException { + List roleIds = new ArrayList<>(); // Get role id list of the user. - List roleIdsOfUser;; try { - roleIdsOfUser = getRoleIdsOfUser(authenticatedUser.getUserId(), authenticatedUser.getTenantDomain()); + List roleIdsOfUser = getRoleIdsOfUser(authenticatedUser.getUserId(), + authenticatedUser.getTenantDomain()); + if (!roleIdsOfUser.isEmpty()) { + roleIds.addAll(roleIdsOfUser); + } } catch (UserIdNotFoundException e) { throw new ScopeValidationHandlerException("Error while resolving user id of user", e); } // Get groups of the user. List groups = getUserGroups(authenticatedUser); - List roleIdsOfGroups = null; if (groups.isEmpty()) { - roleIdsOfGroups = getRoleIdsOfGroups(groups, authenticatedUser.getTenantDomain()); + List roleIdsOfGroups = getRoleIdsOfGroups(groups, authenticatedUser.getTenantDomain()); + if (!roleIdsOfGroups.isEmpty()) { + roleIds.addAll(roleIdsOfGroups); + } } - List roleIdsOfIdGroups = null; if (authenticatedUser.isFederatedUser()) { - roleIdsOfIdGroups = getRoleIdsOfIdpGroups(getUserIdpGroups(authenticatedUser), + List roleIdsOfIdGroups = getRoleIdsOfIdpGroups(getUserIdpGroups(authenticatedUser), authenticatedUser.getTenantDomain()); + if (!roleIdsOfIdGroups.isEmpty()) { + roleIds.addAll(roleIdsOfIdGroups); + } } - List roleIds = null; - if (roleIdsOfUser != null && roleIdsOfGroups != null && roleIdsOfIdGroups != null) { - roleIds = Stream.concat(Stream.concat(roleIdsOfUser.stream(), roleIdsOfGroups.stream()), - roleIdsOfIdGroups.stream()) - .collect(Collectors.toList()); - } - if (roleIds != null && !roleIds.isEmpty()) { + if (!roleIds.isEmpty()) { return getFilteredRoleIds(roleIds, appId, authenticatedUser.getTenantDomain()); } return new ArrayList<>(); @@ -188,7 +193,12 @@ private List getUserGroups(AuthenticatedUser authenticatedUser) ((AbstractUserStoreManager) userStoreManager).getGroupListOfUser(authenticatedUser.getUserId(), null, null); for (Group group : groups) { - userGroups.add(group.getGroupName()); + String groupName = group.getGroupName(); + String groupDomainName = UserCoreUtil.extractDomainFromName(groupName); + if (!INTERNAL_DOMAIN.equalsIgnoreCase(groupDomainName) && + !APPLICATION_DOMAIN.equalsIgnoreCase(groupDomainName)) { + userGroups.add(group.getGroupID()); + } } } catch (UserIdNotFoundException | IdentityOAuth2Exception e) { throw new ScopeValidationHandlerException(e.getMessage(), e); From a7aac524919888276a57c5044e4037205111b496 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Thu, 19 Oct 2023 22:00:56 +0530 Subject: [PATCH 08/29] fix getuser group --- .../internal/OAuthComponentServiceHolder.java | 34 +++++++++---------- .../internal/OAuth2ServiceComponent.java | 23 +++++++++++++ .../DefaultOAuth2ScopeValidator.java | 2 +- .../impl/RoleBasedScopeValidationHandler.java | 7 ++-- 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java index 31579797db0..ba3a4d7f17d 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java @@ -57,7 +57,7 @@ public class OAuthComponentServiceHolder { private List tokenBindingMetaDataDTOs = new ArrayList<>(); private OAuthAdminServiceImpl oAuthAdminService; private List scopeValidators = new ArrayList<>(); - private List scopeValidatorPolicyHandlers = new ArrayList<>(); + private List scopeValidationHandlers = new ArrayList<>(); private Map oAuthApplicationMgtListeners = new TreeMap<>(); private RoleManagementService roleManagementService; private OrganizationUserResidentResolverService organizationUserResidentResolverService; @@ -106,43 +106,43 @@ public void setScopeValidators(List scopeValidators) { } /** - * Get the list of scope validator policy handler implementations available. + * Get the list of scope validation handler implementations available. * - * @return ScopeValidatorPolicyHandler returns a list ot scope validator policy handler. + * @return ScopeValidationHandler returns a list ot scope validation policy handler. */ - public List getScopeValidatorPolicyHandlers() { + public List getScopeValidationHandlers() { - return scopeValidatorPolicyHandlers; + return scopeValidationHandlers; } /** - * Add scope validator policy handler implementation. + * Add scope validation handler implementation. * - * @param scopeValidatorPolicyHandler Scope validator policy handler implementation. + * @param scopeValidationHandler Scope validation handler implementation. */ - public void addScopeValidatorPolicyHandler(ScopeValidationHandler scopeValidatorPolicyHandler) { + public void addScopeValidationHandler(ScopeValidationHandler scopeValidationHandler) { - scopeValidatorPolicyHandlers.add(scopeValidatorPolicyHandler); + scopeValidationHandlers.add(scopeValidationHandler); } /** - * Remove scope validator policy handler implementation. + * Remove scope validation policy implementation. * - * @param scopeValidatorPolicyHandler Scope validator policy handler implementation. + * @param scopeValidationHandler Scope validation policy implementation. */ - public void removeScopeValidatorPolicyHandler(ScopeValidationHandler scopeValidatorPolicyHandler) { + public void removeScopeValidationHandler(ScopeValidationHandler scopeValidationHandler) { - scopeValidatorPolicyHandlers.remove(scopeValidatorPolicyHandler); + scopeValidationHandlers.remove(scopeValidationHandler); } /** - * Set a list of scope validator policy handler implementations. + * Set a list of scope validation handler implementations. * - * @param scopeValidatorPolicyHandlers List of Scope validator policy handler implementation. + * @param scopeValidationHandlers List of Scope validation handler implementation. */ - public void setScopeValidatorPolicyHandlers(List scopeValidatorPolicyHandlers) { + public void setScopeValidatorPolicyHandlers(List scopeValidationHandlers) { - this.scopeValidatorPolicyHandlers = scopeValidatorPolicyHandlers; + this.scopeValidationHandlers = scopeValidationHandlers; } private OAuthComponentServiceHolder() { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java index 31af2fff71e..e6fe3cc9203 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java @@ -616,6 +616,29 @@ protected void removeScopeValidatorService(ScopeValidator scopeValidator) { OAuthComponentServiceHolder.getInstance().removeScopeValidator(scopeValidator); } + @Reference( + name = "scope.validator.handler", + service = ScopeValidationHandler.class, + cardinality = ReferenceCardinality.MULTIPLE, + policy = ReferencePolicy.DYNAMIC, + unbind = "removeScopeValidationHandler" + ) + protected void addScopeValidationHandler(ScopeValidationHandler scopeValidationHandler) { + + if (log.isDebugEnabled()) { + log.debug("Adding the Scope validation handler Service : " + scopeValidationHandler.getName()); + } + OAuthComponentServiceHolder.getInstance().addScopeValidationHandler(scopeValidationHandler); + } + + protected void removeScopeValidationHandler(ScopeValidationHandler scopeValidationHandler) { + + if (log.isDebugEnabled()) { + log.debug("Removing the Scope validator Service : " + scopeValidationHandler.getName()); + } + OAuthComponentServiceHolder.getInstance().removeScopeValidationHandler(scopeValidationHandler); + } + @Reference( name = "IdentityProviderManager", service = org.wso2.carbon.idp.mgt.IdpManager.class, diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index 9339f99632c..2229cebe001 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -99,7 +99,7 @@ private List getAuthorizedScopes(List requestedScopes, Authentic } List authorizedScopesList = getAuthorizedScopes(appId, tenantDomain); List scopeValidationHandlers = - OAuthComponentServiceHolder.getInstance().getScopeValidatorPolicyHandlers(); + OAuthComponentServiceHolder.getInstance().getScopeValidationHandlers(); Map> validatedScopesByHandler = new HashMap<>(); for (AuthorizedScopes authorizedScopes: authorizedScopesList) { String policyId = authorizedScopes.getPolicyId(); diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java index 538d5cf4a15..c5262a47755 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java @@ -37,7 +37,6 @@ import java.util.Map; import java.util.regex.Pattern; import java.util.stream.Collectors; -import java.util.stream.Stream; import static org.wso2.carbon.user.core.UserCoreConstants.APPLICATION_DOMAIN; import static org.wso2.carbon.user.core.UserCoreConstants.INTERNAL_DOMAIN; @@ -105,10 +104,10 @@ private List getUserRoles(AuthenticatedUser authenticatedUser, String ap } } if (authenticatedUser.isFederatedUser()) { - List roleIdsOfIdGroups = getRoleIdsOfIdpGroups(getUserIdpGroups(authenticatedUser), + List roleIdsOfIdpGroups = getRoleIdsOfIdpGroups(getUserIdpGroups(authenticatedUser), authenticatedUser.getTenantDomain()); - if (!roleIdsOfIdGroups.isEmpty()) { - roleIds.addAll(roleIdsOfIdGroups); + if (!roleIdsOfIdpGroups.isEmpty()) { + roleIds.addAll(roleIdsOfIdpGroups); } } if (!roleIds.isEmpty()) { From 91e08be38b8258a68f461700e5546e27159e7d6f Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Fri, 20 Oct 2023 11:19:37 +0530 Subject: [PATCH 09/29] fix null exception --- .../oauth2/validators/DefaultOAuth2ScopeValidator.java | 8 ++++---- .../policyhandler/impl/M2MScopeValidationHandler.java | 2 +- .../impl/RoleBasedScopeValidationHandler.java | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index 2229cebe001..3a774f9cdcf 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -113,8 +113,8 @@ private List getAuthorizedScopes(List requestedScopes, Authentic policyContext.setValidatedScopesByHandler(validatedScopesByHandler); List validatedScopes; try { - validatedScopes = scopeValidationHandler.validateScopes(authorizedScopes.getScopes(), - requestedScopes, policyContext); + validatedScopes = scopeValidationHandler.validateScopes(requestedScopes, + authorizedScopes.getScopes(), policyContext); } catch (ScopeValidationHandlerException e) { throw new IdentityOAuth2Exception("Error while validating policies roles from " + "authorization service.", e); @@ -125,12 +125,12 @@ private List getAuthorizedScopes(List requestedScopes, Authentic } // If "NoPolicy" exists, add all its scopes to the result - Set scopes = new HashSet<>(validatedScopesByHandler.getOrDefault("NoPolicy", + Set scopes = new HashSet<>(validatedScopesByHandler.getOrDefault("NoPolicyScopeValidationHandler", Collections.emptyList())); // Separate "NoPolicy" and get the intersection of the rest of the scopes validated by other validators List> otherHandlerScopes = new ArrayList<>(validatedScopesByHandler.values()); - otherHandlerScopes.remove(validatedScopesByHandler.get("NoPolicy")); + otherHandlerScopes.remove(validatedScopesByHandler.get("NoPolicyScopeValidationHandler")); List intersection = new ArrayList<>(); if (!otherHandlerScopes.isEmpty()) { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java index becac24de43..f82357952a0 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java @@ -31,7 +31,7 @@ public List validateScopes(List requestedScopes, List ap @Override public String getPolicyID() { - return null; + return "M2M"; } @Override diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java index c5262a47755..2ad2dd5c079 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java @@ -128,7 +128,7 @@ private List getRoleIdsAssociatedWithApp(String appId, String tenantDoma try { return OAuth2ServiceComponentHolder.getApplicationMgtService() - .getAssociatedRolesOfApplication(appId, tenantDomain).stream().map(RoleV2::getName) + .getAssociatedRolesOfApplication(appId, tenantDomain).stream().map(RoleV2::getId) .collect(Collectors.toCollection(ArrayList::new)); } catch (IdentityApplicationManagementException e) { throw new ScopeValidationHandlerException("Error while retrieving role id list of app : " + appId From ef401fe997dcc62059357c93f52332931e5da865 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Sat, 21 Oct 2023 14:43:38 +0530 Subject: [PATCH 10/29] introduce islegacyauthzruntime --- .../identity/oauth2/authz/AuthorizationHandlerManager.java | 5 ++--- .../oauth2/authz/handlers/AbstractResponseTypeHandler.java | 2 +- .../carbon/identity/oauth2/token/AccessTokenIssuer.java | 7 +++---- .../handlers/grant/AbstractAuthorizationGrantHandler.java | 2 +- .../org/wso2/carbon/identity/oauth2/util/OAuth2Util.java | 5 +++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java index 299b9e23c1c..c44537de4c5 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java @@ -273,13 +273,12 @@ private void validateRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, ResponseTypeHandler authzHandler) throws IdentityOAuth2Exception, IdentityOAuth2UnauthorizedScopeException { - boolean isScopeValidationOldBehaviourEnabled = OAuth2Util.isScopeValidationOldBehaviourEnabled(); // Get allowed scopes that are specified in the server level. List requestedAllowedScopes = getAllowedScopesFromRequestedScopes(authzReqMsgCtx); // Remove the system level allowed scopes from requested scopes for further validation. removeAllowedScopesFromRequestedScopes(authzReqMsgCtx, requestedAllowedScopes); List authorizedScopes = null; - if (isScopeValidationOldBehaviourEnabled) { + if (OAuth2Util.isLegacyAuthzRuntime()) { // If it is management app, we validate internal scopes in the requested scopes. String[] authorizedInternalScopes = new String[0]; log.debug("Handling the internal scope validation."); @@ -306,7 +305,7 @@ private void validateRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, boolean isValid = validateScopes(authzReqMsgCtx, authzHandler); boolean isValidatedScopesContainsInRequestedScopes = isValidatedScopesContainsInRequestedScopes(authzReqMsgCtx); if (isValid && isValidatedScopesContainsInRequestedScopes) { - if (isScopeValidationOldBehaviourEnabled) { + if (OAuth2Util.isLegacyAuthzRuntime()) { // Add authorized internal scopes to the request for sending in the response. addAuthorizedInternalScopes(authzReqMsgCtx, authzReqMsgCtx.getAuthorizedInternalScopes()); } else { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java index 8cf1e441acb..b5c56d4f7d5 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java @@ -234,7 +234,7 @@ public OAuth2AuthorizeRespDTO initResponse(OAuthAuthzReqMessageContext oauthAuth private boolean hasValidationByApplicationScopeValidatorsFailed(OAuthAuthzReqMessageContext authzReqMessageContext) throws IdentityOAuth2Exception { - if (OAuth2Util.isScopeValidationOldBehaviourEnabled()) { + if (OAuth2Util.isLegacyAuthzRuntime()) { return !Oauth2ScopeUtils.validateByApplicationScopeValidator(null, authzReqMessageContext); } return true; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java index 67d5581fc52..aab515cbd0d 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java @@ -597,7 +597,6 @@ private Optional getAuthzGrantCacheEntryFromAuthzC private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception { - boolean isScopeValidationOldBehaviourEnabled = OAuth2Util.isScopeValidationOldBehaviourEnabled(); OAuth2AccessTokenReqDTO tokenReqDTO = tokReqMsgCtx.getOauth2AccessTokenReqDTO(); String grantType = tokenReqDTO.getGrantType(); if (GrantType.AUTHORIZATION_CODE.toString().equals(grantType)) { @@ -679,7 +678,7 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I if (log.isDebugEnabled()) { log.debug("Handling the internal scope validation."); } - if (isScopeValidationOldBehaviourEnabled) { + if (OAuth2Util.isLegacyAuthzRuntime()) { // Execute Internal SCOPE Validation. JDBCPermissionBasedInternalScopeValidator scopeValidator = new JDBCPermissionBasedInternalScopeValidator(); @@ -716,7 +715,7 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I Those scopes should not send to the other scopes validators. Thus remove the scopes from the tokReqMsgCtx. Will be added to the response after executing the other scope validators. */ - if (isScopeValidationOldBehaviourEnabled) { + if (OAuth2Util.isLegacyAuthzRuntime()) { removeInternalScopes(tokReqMsgCtx); // Adding the authorized internal scopes to tokReqMsgCtx for any special validators to use. @@ -741,7 +740,7 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I boolean isValidScope = authzGrantHandler.validateScope(tokReqMsgCtx); if (isValidScope) { // Add authorized internal scopes to the request for sending in the response. - if (isScopeValidationOldBehaviourEnabled) { + if (OAuth2Util.isLegacyAuthzRuntime()) { addAuthorizedInternalScopes(tokReqMsgCtx, tokReqMsgCtx.getAuthorizedInternalScopes()); } else { addAuthorizedScopes(tokReqMsgCtx, authorizedScopes); diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java index 4e3b03bc4bc..e05d4c93d4c 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java @@ -1041,7 +1041,7 @@ private OAuth2Service getOauth2Service() { private boolean hasValidationByApplicationScopeValidatorsFailed(OAuthTokenReqMessageContext tokenReqMsgContext) throws IdentityOAuth2Exception { - if (OAuth2Util.isScopeValidationOldBehaviourEnabled()) { + if (OAuth2Util.isLegacyAuthzRuntime()) { return !Oauth2ScopeUtils.validateByApplicationScopeValidator(tokenReqMsgContext, null); } return true; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java index 20356cb7a87..49dfd892bd2 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java @@ -63,6 +63,7 @@ import org.apache.oltu.oauth2.common.utils.OAuthUtils; import org.json.JSONException; import org.json.JSONObject; +import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.core.util.KeyStoreManager; import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; @@ -4961,8 +4962,8 @@ public static String[] extractCredentialsFromAuthzHeader(HttpServletRequest requ return OAuthUtils.decodeClientAuthenticationHeader(authorizationHeader); } - public static boolean isScopeValidationOldBehaviourEnabled() { + public static boolean isLegacyAuthzRuntime() { - return true; + return CarbonConstants.ENABLE_LEGACY_AUTHZ_RUNTIME; } } From 01b9aa930bff823b72e1f7010dfdcd1344815b2d Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Sat, 21 Oct 2023 16:04:56 +0530 Subject: [PATCH 11/29] fix legacy app validator skip return --- .../identity/oauth2/authz/AuthorizationHandlerManager.java | 1 - .../oauth2/authz/handlers/AbstractResponseTypeHandler.java | 2 +- .../token/handlers/grant/AbstractAuthorizationGrantHandler.java | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java index c44537de4c5..aa2c64a252c 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java @@ -289,7 +289,6 @@ private void validateRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, // Adding the authorized internal scopes to tokReqMsgCtx for any special validators to use. authzReqMsgCtx.setAuthorizedInternalScopes(authorizedInternalScopes); } else { - // Engage new scope validator authorizedScopes = getAuthorizedScopes(authzReqMsgCtx); removeAuthorizedScopesFromRequestedScopes(authzReqMsgCtx, authorizedScopes); diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java index b5c56d4f7d5..ef771a53d2a 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java @@ -237,6 +237,6 @@ private boolean hasValidationByApplicationScopeValidatorsFailed(OAuthAuthzReqMes if (OAuth2Util.isLegacyAuthzRuntime()) { return !Oauth2ScopeUtils.validateByApplicationScopeValidator(null, authzReqMessageContext); } - return true; + return false; } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java index e05d4c93d4c..e4d04ea7442 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java @@ -1044,7 +1044,7 @@ private boolean hasValidationByApplicationScopeValidatorsFailed(OAuthTokenReqMes if (OAuth2Util.isLegacyAuthzRuntime()) { return !Oauth2ScopeUtils.validateByApplicationScopeValidator(tokenReqMsgContext, null); } - return true; + return false; } /** From 61125a75e03c045bcba51a2138a60343d0223196 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Sun, 22 Oct 2023 00:24:29 +0530 Subject: [PATCH 12/29] fix formatting --- .../DefaultOAuth2ScopeValidator.java | 81 +++++++++++++++++-- .../policyhandler/ScopeValidationContext.java | 51 ++++++++++++ .../policyhandler/ScopeValidationHandler.java | 28 +++++++ .../impl/RoleBasedScopeValidationHandler.java | 57 +++++++++++++ 4 files changed, 211 insertions(+), 6 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index 3a774f9cdcf..ece3ef30414 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -42,6 +42,13 @@ public class DefaultOAuth2ScopeValidator { private static final Log LOG = LogFactory.getLog(DefaultOAuth2ScopeValidator.class); + /** + * Validate scope. + * + * @param authzReqMessageContext AuthzReqMessageContext. + * @return List of scopes. + * @throws IdentityOAuth2Exception Error when performing the scope validation. + */ public List validateScope(OAuthAuthzReqMessageContext authzReqMessageContext) throws IdentityOAuth2Exception { @@ -59,6 +66,13 @@ public List validateScope(OAuthAuthzReqMessageContext authzReqMessageCon null, tenantDomain); } + /** + * Validate scope. + * + * @param tokenReqMessageContext tokenReqMessageContext. + * @return List of scopes. + * @throws IdentityOAuth2Exception Error when performing the scope validation. + */ public List validateScope(OAuthTokenReqMessageContext tokenReqMessageContext) throws IdentityOAuth2Exception { @@ -77,9 +91,20 @@ public List validateScope(OAuthTokenReqMessageContext tokenReqMessageCon tenantDomain); } + /** + * Get authorized scopes. + * + * @param requestedScopes Requested scopes. + * @param authenticatedUser Authenticated user. + * @param appId App ID. + * @param grantType Grant type. + * @param tenantDomain Tenant domain. + * @return Authorized scopes. + * @throws IdentityOAuth2Exception if any error occurs during getting authorized scopes. + */ private List getAuthorizedScopes(List requestedScopes, AuthenticatedUser authenticatedUser, String appId, String grantType, String tenantDomain) - throws IdentityOAuth2Exception { + throws IdentityOAuth2Exception { // Filter OIDC scopes and add to approved scopes list. if (LOG.isDebugEnabled()) { @@ -97,13 +122,13 @@ private List getAuthorizedScopes(List requestedScopes, Authentic if (requestedScopes.contains(SYSTEM_SCOPE)) { requestedScopes.addAll(getInternalScopes(tenantDomain)); } - List authorizedScopesList = getAuthorizedScopes(appId, tenantDomain); + List authorizedScopesList = getAuthorizedScopes(appId, tenantDomain); List scopeValidationHandlers = OAuthComponentServiceHolder.getInstance().getScopeValidationHandlers(); Map> validatedScopesByHandler = new HashMap<>(); - for (AuthorizedScopes authorizedScopes: authorizedScopesList) { + for (AuthorizedScopes authorizedScopes : authorizedScopesList) { String policyId = authorizedScopes.getPolicyId(); - ScopeValidationContext policyContext = new ScopeValidationContext(); + ScopeValidationContext policyContext = new ScopeValidationContext(); policyContext.setAuthenticatedUser(authenticatedUser); policyContext.setAppId(appId); policyContext.setPolicyId(policyId); @@ -145,6 +170,14 @@ private List getAuthorizedScopes(List requestedScopes, Authentic return approvedScopes; } + /** + * Get the authorized scopes for the given appId and tenant domain. + * + * @param appId App id. + * @param tenantDomain Tenant domain. + * @return Authorized scopes. + * @throws IdentityOAuth2Exception if an error occurs while retrieving authorized scopes for app. + */ private List getAuthorizedScopes(String appId, String tenantDomain) throws IdentityOAuth2Exception { @@ -157,10 +190,17 @@ private List getAuthorizedScopes(String appId, String tenantDo } } + /** + * Get the internal scopes. + * + * @param tenantDomain Tenant domain. + * @return Internal scopes. + * @throws IdentityOAuth2Exception if an error occurs while retrieving internal scopes for tenant domain. + */ private List getInternalScopes(String tenantDomain) throws IdentityOAuth2Exception { try { - List scopes = OAuth2ServiceComponentHolder.getInstance() + List scopes = OAuth2ServiceComponentHolder.getInstance() .getApiResourceManager().getScopesByTenantDomain(tenantDomain, "name sw internal_"); return scopes.stream().map(Scope::getName).collect(Collectors.toCollection(ArrayList::new)); } catch (APIResourceMgtException e) { @@ -169,12 +209,20 @@ private List getInternalScopes(String tenantDomain) throws IdentityOAuth } } + /** + * Get the requested OIDC scopes + * + * @param tenantDomain Tenant domain. + * @param requestedScopes Requested scopes. + * @return Requested OIDC scopes. + * @throws IdentityOAuth2Exception if an error occurs while retrieving oidc scopes. + */ private Set getRequestedOIDCScopes(String tenantDomain, List requestedScopes) throws IdentityOAuth2Exception { OAuthAdminServiceImpl oAuthAdminServiceImpl = OAuth2ServiceComponentHolder.getInstance().getOAuthAdminService(); try { - List oidcScopes = oAuthAdminServiceImpl.getRegisteredOIDCScope(tenantDomain); + List oidcScopes = oAuthAdminServiceImpl.getRegisteredOIDCScope(tenantDomain); return requestedScopes.stream().distinct().filter(oidcScopes::contains).collect(Collectors.toSet()); } catch (IdentityOAuthAdminException e) { throw new IdentityOAuth2Exception("Error while retrieving oidc scopes for tenant domain : " @@ -182,11 +230,26 @@ private Set getRequestedOIDCScopes(String tenantDomain, List req } } + /** + * Remove OIDC scopes from the list. + * + * @param requestedScopes Requested scopes. + * @param oidcScopes OIDC scopes. + * @return List of scopes. + */ private List removeOIDCScopes(List requestedScopes, Set oidcScopes) { return requestedScopes.stream().distinct().filter(s -> !oidcScopes.contains(s)).collect(Collectors.toList()); } + /** + * Get the application resource id for the given client id + * + * @param clientId Client Id. + * @param tenantName Tenant name. + * @return Application resource id. + * @throws IdentityOAuth2Exception if an error occurs while retrieving application resource id. + */ private String getApplicationId(String clientId, String tenantName) throws IdentityOAuth2Exception { ApplicationManagementService applicationMgtService = OAuth2ServiceComponentHolder.getApplicationMgtService(); @@ -198,6 +261,12 @@ private String getApplicationId(String clientId, String tenantName) throws Ident } } + /** + * Checks if the scopes list is empty + * + * @param scopes Scopes list + * @return true if scopes list is empty + */ private boolean isScopesEmpty(String[] scopes) { return ArrayUtils.isEmpty(scopes); diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationContext.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationContext.java index 5aede81f56b..0ce2490a65a 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationContext.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationContext.java @@ -17,51 +17,102 @@ public class ScopeValidationContext { private String policyId; private Map> validatedScopesByHandler; + /** + * Get the authenticated user. + * + * @return AuthenticatedUser. + */ + public AuthenticatedUser getAuthenticatedUser() { return authenticatedUser; } + /** + * Set the authenticated user. + * + * @param authenticatedUser AuthenticatedUser. + */ public void setAuthenticatedUser(AuthenticatedUser authenticatedUser) { this.authenticatedUser = authenticatedUser; } + /** + * Get the application id. + * + * @return Application ID. + */ public String getAppId() { return appId; } + /** + * Set the application id. + * + * @param appId Application ID. + */ public void setAppId(String appId) { this.appId = appId; } + /** + * Get the validated scopes by handler + * + * @return Map of validated scopes. + */ public Map> getValidatedScopesByHandler() { return validatedScopesByHandler; } + /** + * Set the validated scopes by handler. + * + * @param validatedScopesByHandler Map of validated scopes. + */ public void setValidatedScopesByHandler(Map> validatedScopesByHandler) { this.validatedScopesByHandler = validatedScopesByHandler; } + /** + * Get the grant type. + * + * @return Grant type. + */ public String getGrantType() { return grantType; } + /** + * Set the grant type. + * + * @param grantType Grant type. + */ public void setGrantType(String grantType) { this.grantType = grantType; } + /** + * Get the policy id. + * + * @return Policy ID. + */ public String getPolicyId() { return policyId; } + /** + * Set the policy id. + * + * @param policyId Policy ID. + */ public void setPolicyId(String policyId) { this.policyId = policyId; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java index 71fc75988aa..2423343d757 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java @@ -7,11 +7,39 @@ */ public interface ScopeValidationHandler { + /** + * Check if the handler can handle the scope validation + * + * @param scopeValidationContext ScopeValidationContext. + * @return boolean + */ boolean canHandle(ScopeValidationContext scopeValidationContext); + + /** + * Validate scopes. + * + * @param requestedScopes Requested scopes. + * @param appAuthorizedScopes Authorized scopes. + * @param scopeValidationContext ScopeValidationContext. + * @return List of scopes. + * @throws ScopeValidationHandlerException Error when performing the scope validation. + */ List validateScopes(List requestedScopes, List appAuthorizedScopes, ScopeValidationContext scopeValidationContext) throws ScopeValidationHandlerException; + + /** + * Get policy ID. + * + * @return Policy ID. + */ String getPolicyID(); + /** + * Get handler name. + * + * @return Handler name. + */ + String getName(); } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java index 2ad2dd5c079..669f20821ac 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java @@ -69,6 +69,14 @@ public List validateScopes(List requestedScopes, List ap return requestedScopes.stream().filter(filteredScopes::contains).collect(Collectors.toList()); } + /** + * Get the associated scopes for the roles. + * + * @param roles Roles. + * @param tenantDomain Tenant domain. + * @return List of associated scopes. + * @throws ScopeValidationHandlerException if an error occurs while retrieving scope list of roles. + */ private List getAssociatedScopesForRoles(List roles, String tenantDomain) throws ScopeValidationHandlerException { @@ -81,6 +89,14 @@ private List getAssociatedScopesForRoles(List roles, String tena } } + /** + * Get the user roles. + * + * @param authenticatedUser AuthenticatedUser. + * @param appId App id. + * @return User roles. + * @throws ScopeValidationHandlerException if an error occurs while retrieving user roles. + */ private List getUserRoles(AuthenticatedUser authenticatedUser, String appId) throws ScopeValidationHandlerException { @@ -116,6 +132,15 @@ private List getUserRoles(AuthenticatedUser authenticatedUser, String ap return new ArrayList<>(); } + /** + * Get the filtered role ids. + * + * @param roleId Role id list. + * @param appId App id. + * @param tenantDomain Tenant domain. + * @return Filtered role ids. + * @throws ScopeValidationHandlerException if an error occurs while retrieving filtered role id list. + */ private List getFilteredRoleIds(List roleId, String appId, String tenantDomain) throws ScopeValidationHandlerException { @@ -123,6 +148,14 @@ private List getFilteredRoleIds(List roleId, String appId, Strin return roleId.stream().distinct().filter(rolesAssociatedWithApp::contains).collect(Collectors.toList()); } + /** + * Get the role ids associated with app. + * + * @param appId App id. + * @param tenantDomain Tenant domain. + * @return Role ids associated with app. + * @throws ScopeValidationHandlerException if an error occurs while retrieving role id list of app. + */ private List getRoleIdsAssociatedWithApp(String appId, String tenantDomain) throws ScopeValidationHandlerException { @@ -136,6 +169,14 @@ private List getRoleIdsAssociatedWithApp(String appId, String tenantDoma } } + /** + * Get the role ids of user. + * + * @param userId User id. + * @param tenantDomain Tenant domain. + * @return Role ids of user. + * @throws ScopeValidationHandlerException if an error occurs while retrieving role id list of user. + */ private List getRoleIdsOfUser(String userId, String tenantDomain) throws ScopeValidationHandlerException { try { @@ -147,6 +188,14 @@ private List getRoleIdsOfUser(String userId, String tenantDomain) throws } } + /** + * Get the role ids of groups. + * + * @param groups Groups. + * @param tenantDomain Tenant domain. + * @return Role ids of groups. + * @throws ScopeValidationHandlerException if an error occurs while retrieving role id list of groups. + */ private List getRoleIdsOfGroups(List groups, String tenantDomain) throws ScopeValidationHandlerException { @@ -159,6 +208,14 @@ private List getRoleIdsOfGroups(List groups, String tenantDomain } } + /** + * Get the role ids of idp groups + * + * @param groups Groups. + * @param tenantDomain Tenant domain. + * @return Role ids of idp groups. + * @throws ScopeValidationHandlerException if an error occurs while retrieving role id list of idp groups. + */ private List getRoleIdsOfIdpGroups(List groups, String tenantDomain) throws ScopeValidationHandlerException { From 392112bae31c00a1a0452c7eb1f73d36b793c86b Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Tue, 24 Oct 2023 11:14:28 +0530 Subject: [PATCH 13/29] fix xacml engagement --- .../oauth2/authz/handlers/AbstractResponseTypeHandler.java | 5 +---- .../handlers/grant/AbstractAuthorizationGrantHandler.java | 5 +---- .../wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java | 5 +++++ .../policyhandler/impl/RoleBasedScopeValidationHandler.java | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java index ef771a53d2a..bc1b5a78bb0 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/handlers/AbstractResponseTypeHandler.java @@ -234,9 +234,6 @@ public OAuth2AuthorizeRespDTO initResponse(OAuthAuthzReqMessageContext oauthAuth private boolean hasValidationByApplicationScopeValidatorsFailed(OAuthAuthzReqMessageContext authzReqMessageContext) throws IdentityOAuth2Exception { - if (OAuth2Util.isLegacyAuthzRuntime()) { - return !Oauth2ScopeUtils.validateByApplicationScopeValidator(null, authzReqMessageContext); - } - return false; + return !Oauth2ScopeUtils.validateByApplicationScopeValidator(null, authzReqMessageContext); } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java index e4d04ea7442..345023bae42 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandler.java @@ -1041,10 +1041,7 @@ private OAuth2Service getOauth2Service() { private boolean hasValidationByApplicationScopeValidatorsFailed(OAuthTokenReqMessageContext tokenReqMsgContext) throws IdentityOAuth2Exception { - if (OAuth2Util.isLegacyAuthzRuntime()) { - return !Oauth2ScopeUtils.validateByApplicationScopeValidator(tokenReqMsgContext, null); - } - return false; + return !Oauth2ScopeUtils.validateByApplicationScopeValidator(tokenReqMsgContext, null); } /** diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java index 6999cfbca8f..c9aede1d8c1 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java @@ -259,6 +259,11 @@ private static boolean iterateOAuth2ScopeValidators(OAuthAuthzReqMessageContext .getOAuth2ScopeValidators(); // Iterate through all available scope validators. for (OAuth2ScopeValidator validator : oAuth2ScopeValidators) { + + if (!OAuth2Util.isLegacyAuthzRuntime() && "Role based scope validator".equals(validator + .getValidatorName())) { + return true; + } // Validate the scopes from the validator only if it's configured in the OAuth app. if (validator != null && appScopeValidators.contains(validator.getValidatorName())) { if (log.isDebugEnabled()) { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java index 669f20821ac..d84a3befe12 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java @@ -20,7 +20,7 @@ import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationContext; import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandlerException; -import org.wso2.carbon.identity.role.v2.mgt.core.IdentityRoleManagementException; +import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementException; import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; From c68a58db39cb82ee5e0370833b6d76e5940047f7 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Tue, 24 Oct 2023 13:01:53 +0530 Subject: [PATCH 14/29] fix user role resolver --- .../policyhandler/impl/NoPolicyScopeValidationHandler.java | 2 +- .../policyhandler/impl/RoleBasedScopeValidationHandler.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java index b951c08e593..48f3299aa4b 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java @@ -29,7 +29,7 @@ public List validateScopes(List requestedScopes, List ap @Override public String getPolicyID() { - return "NoPolicy"; + return "NO POLICY"; } @Override diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java index d84a3befe12..f1522c8d072 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java @@ -113,7 +113,7 @@ private List getUserRoles(AuthenticatedUser authenticatedUser, String ap } // Get groups of the user. List groups = getUserGroups(authenticatedUser); - if (groups.isEmpty()) { + if (!groups.isEmpty()) { List roleIdsOfGroups = getRoleIdsOfGroups(groups, authenticatedUser.getTenantDomain()); if (!roleIdsOfGroups.isEmpty()) { roleIds.addAll(roleIdsOfGroups); From 7d590e9ccb7106b6d7dfd9824c4c68da500ea211 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Tue, 24 Oct 2023 15:23:05 +0530 Subject: [PATCH 15/29] remove registered scopes --- .../DefaultOAuth2ScopeValidator.java | 77 ++++++++++++++++++- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index ece3ef30414..eeb71b8f3be 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -62,8 +62,10 @@ public List validateScope(OAuthAuthzReqMessageContext authzReqMessageCon String tenantDomain = authzReqMessageContext.getAuthorizationReqDTO().getTenantDomain(); String clientId = authzReqMessageContext.getAuthorizationReqDTO().getConsumerKey(); String appId = getApplicationId(clientId, tenantDomain); - return getAuthorizedScopes(requestedScopes, authzReqMessageContext.getAuthorizationReqDTO().getUser(), appId, - null, tenantDomain); + List authorizedScopes = getAuthorizedScopes(requestedScopes, authzReqMessageContext + .getAuthorizationReqDTO().getUser(), appId, null, tenantDomain); + removeRegisteredScopes(authzReqMessageContext); + return authorizedScopes; } /** @@ -87,8 +89,10 @@ public List validateScope(OAuthTokenReqMessageContext tokenReqMessageCon String clientId = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getClientId(); String appId = getApplicationId(clientId, tenantDomain); String grantType = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getGrantType(); - return getAuthorizedScopes(requestedScopes, tokenReqMessageContext.getAuthorizedUser(), appId, grantType, - tenantDomain); + List authorizedScopes = getAuthorizedScopes(requestedScopes, tokenReqMessageContext + .getAuthorizedUser(), appId, grantType, tenantDomain); + removeRegisteredScopes(tokenReqMessageContext); + return authorizedScopes; } /** @@ -209,6 +213,71 @@ private List getInternalScopes(String tenantDomain) throws IdentityOAuth } } + /** + * Get the registered scopes. + * + * @param tenantDomain Tenant domain. + * @return Registered scopes. + * @throws IdentityOAuth2Exception if an error occurs while retrieving internal scopes for tenant domain. + */ + private List getRegisteredScopes(String tenantDomain) throws IdentityOAuth2Exception { + + try { + List scopes = OAuth2ServiceComponentHolder.getInstance() + .getApiResourceManager().getScopesByTenantDomain(tenantDomain, null); + return scopes.stream().map(Scope::getName).collect(Collectors.toCollection(ArrayList::new)); + } catch (APIResourceMgtException e) { + throw new IdentityOAuth2Exception("Error while retrieving internal scopes for tenant domain : " + + tenantDomain, e); + } + } + + /** + * Remove registered scopes. + * + * @param authzReqMessageContext OAuthAuthzReqMessageContext + * @throws IdentityOAuth2Exception Error while remove registered scopes. + */ + private void removeRegisteredScopes(OAuthAuthzReqMessageContext authzReqMessageContext) + throws IdentityOAuth2Exception { + + if (authzReqMessageContext.getAuthorizationReqDTO().getScopes() == null) { + return; + } + List registeredScopes = getRegisteredScopes(authzReqMessageContext.getAuthorizationReqDTO() + .getTenantDomain()); + List scopes = new ArrayList<>(); + for (String scope : authzReqMessageContext.getAuthorizationReqDTO().getScopes()) { + if (!registeredScopes.contains(scope)) { + scopes.add(scope); + } + } + authzReqMessageContext.getAuthorizationReqDTO().setScopes(scopes.toArray(new String[0])); + } + + /** + * Remove registered scopes. + * + * @param tokenReqMessageContext OAuthTokenReqMessageContext + * @throws IdentityOAuth2Exception Error while remove registered scopes. + */ + private void removeRegisteredScopes(OAuthTokenReqMessageContext tokenReqMessageContext) + throws IdentityOAuth2Exception { + + if (tokenReqMessageContext.getScope() == null) { + return; + } + List registeredScopes = getRegisteredScopes(tokenReqMessageContext.getOauth2AccessTokenReqDTO() + .getTenantDomain()); + List scopes = new ArrayList<>(); + for (String scope : tokenReqMessageContext.getScope()) { + if (!registeredScopes.contains(scope)) { + scopes.add(scope); + } + } + tokenReqMessageContext.setScope(scopes.toArray(new String[0])); + } + /** * Get the requested OIDC scopes * From e60d41004e569ca3972ed480ec51b12cec9d399f Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Tue, 24 Oct 2023 18:01:05 +0530 Subject: [PATCH 16/29] add authzutil class --- .../internal/OAuthComponentServiceHolder.java | 2 +- .../internal/OAuth2ServiceComponent.java | 8 +- .../AuthzUtil.java} | 198 +++++------------- .../DefaultOAuth2ScopeValidator.java | 17 +- .../ScopeValidationContext.java | 2 +- .../ScopeValidationHandler.java | 2 +- .../ScopeValidationHandlerException.java | 2 +- .../impl/M2MScopeValidationHandler.java | 8 +- .../impl/NoPolicyScopeValidationHandler.java | 8 +- .../impl/RoleBasedScopeValidationHandler.java | 108 ++++++++++ 10 files changed, 192 insertions(+), 163 deletions(-) rename components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/{validators/policyhandler/impl/RoleBasedScopeValidationHandler.java => util/AuthzUtil.java} (60%) rename components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/{policyhandler => validationhandler}/ScopeValidationContext.java (97%) rename components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/{policyhandler => validationhandler}/ScopeValidationHandler.java (94%) rename components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/{policyhandler => validationhandler}/ScopeValidationHandlerException.java (89%) rename components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/{policyhandler => validationhandler}/impl/M2MScopeValidationHandler.java (74%) rename components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/{policyhandler => validationhandler}/impl/NoPolicyScopeValidationHandler.java (71%) create mode 100644 components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java index bd5f61cc2c8..52480685d0b 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthComponentServiceHolder.java @@ -30,8 +30,8 @@ import org.wso2.carbon.identity.oauth2.dao.AccessTokenDAO; import org.wso2.carbon.identity.oauth2.dao.TokenManagementDAO; import org.wso2.carbon.identity.oauth2.token.handlers.response.AccessTokenResponseHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; import org.wso2.carbon.identity.oauth2.validators.scope.ScopeValidator; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandler; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; import org.wso2.carbon.identity.organization.management.service.OrganizationUserResidentResolverService; import org.wso2.carbon.identity.role.mgt.core.RoleManagementService; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java index 1154688b782..62a59f9c984 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java @@ -79,12 +79,12 @@ import org.wso2.carbon.identity.oauth2.token.bindings.impl.SSOSessionBasedTokenBinder; import org.wso2.carbon.identity.oauth2.token.handlers.claims.JWTAccessTokenClaimProvider; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.M2MScopeValidationHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.NoPolicyScopeValidationHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.impl.RoleBasedScopeValidationHandler; import org.wso2.carbon.identity.oauth2.validators.scope.RoleBasedScopeIssuer; import org.wso2.carbon.identity.oauth2.validators.scope.ScopeValidator; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.impl.M2MScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.impl.NoPolicyScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.impl.RoleBasedScopeValidationHandler; import org.wso2.carbon.identity.openidconnect.OpenIDConnectClaimFilter; import org.wso2.carbon.identity.openidconnect.OpenIDConnectClaimFilterImpl; import org.wso2.carbon.identity.openidconnect.dao.ScopeClaimMappingDAO; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java similarity index 60% rename from components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java rename to components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java index f1522c8d072..9d585417448 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/RoleBasedScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java @@ -1,4 +1,4 @@ -package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; +package org.wso2.carbon.identity.oauth2.util; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -7,19 +7,11 @@ 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; import org.wso2.carbon.identity.application.common.model.IdPGroup; import org.wso2.carbon.identity.application.common.model.IdentityProvider; -import org.wso2.carbon.identity.application.common.model.RoleV2; -import org.wso2.carbon.identity.oauth.common.OAuthConstants; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; -import org.wso2.carbon.identity.oauth2.util.OAuth2Util; -import org.wso2.carbon.identity.oauth2.validators.DefaultOAuth2ScopeValidator; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationContext; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandlerException; import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementException; import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; import org.wso2.carbon.user.api.UserStoreException; @@ -42,63 +34,21 @@ import static org.wso2.carbon.user.core.UserCoreConstants.INTERNAL_DOMAIN; /** - * RoleBasedScopeValidationHandler + * AuthzUtil */ -public class RoleBasedScopeValidationHandler implements ScopeValidationHandler { +public class AuthzUtil { - private static final Log LOG = LogFactory.getLog(DefaultOAuth2ScopeValidator.class); - - @Override - public boolean canHandle(ScopeValidationContext scopeValidationContext) { - - return getPolicyID().equals(scopeValidationContext.getPolicyId()) - && !OAuthConstants.GrantTypes.CLIENT_CREDENTIALS.equals(scopeValidationContext.getGrantType()); - } - - @Override - public List validateScopes(List requestedScopes, List appAuthorizedScopes, - ScopeValidationContext scopeValidationContext) - throws ScopeValidationHandlerException { - - List userRoles = getUserRoles(scopeValidationContext.getAuthenticatedUser(), - scopeValidationContext.getAppId()); - List associatedScopes = getAssociatedScopesForRoles(userRoles, - scopeValidationContext.getAuthenticatedUser().getTenantDomain()); - List filteredScopes = appAuthorizedScopes.stream().filter(associatedScopes::contains) - .collect(Collectors.toList()); - return requestedScopes.stream().filter(filteredScopes::contains).collect(Collectors.toList()); - } - - /** - * Get the associated scopes for the roles. - * - * @param roles Roles. - * @param tenantDomain Tenant domain. - * @return List of associated scopes. - * @throws ScopeValidationHandlerException if an error occurs while retrieving scope list of roles. - */ - private List getAssociatedScopesForRoles(List roles, String tenantDomain) - throws ScopeValidationHandlerException { - - try { - return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() - .getPermissionListOfRoles(roles, tenantDomain); - } catch (IdentityRoleManagementException e) { - throw new ScopeValidationHandlerException("Error while retrieving scope list of roles : " - + StringUtils.join(roles, ",") + "tenant domain : " + tenantDomain, e); - } - } + private static final Log LOG = LogFactory.getLog(AuthzUtil.class); /** * Get the user roles. * * @param authenticatedUser AuthenticatedUser. - * @param appId App id. * @return User roles. - * @throws ScopeValidationHandlerException if an error occurs while retrieving user roles. + * @throws IdentityOAuth2Exception if an error occurs while retrieving user roles. */ - private List getUserRoles(AuthenticatedUser authenticatedUser, String appId) - throws ScopeValidationHandlerException { + public static List getUserRoles(AuthenticatedUser authenticatedUser) + throws IdentityOAuth2Exception { List roleIds = new ArrayList<>(); // Get role id list of the user. @@ -109,7 +59,7 @@ private List getUserRoles(AuthenticatedUser authenticatedUser, String ap roleIds.addAll(roleIdsOfUser); } } catch (UserIdNotFoundException e) { - throw new ScopeValidationHandlerException("Error while resolving user id of user", e); + throw new IdentityOAuth2Exception("Error while resolving user id of user", e); } // Get groups of the user. List groups = getUserGroups(authenticatedUser); @@ -126,46 +76,26 @@ private List getUserRoles(AuthenticatedUser authenticatedUser, String ap roleIds.addAll(roleIdsOfIdpGroups); } } - if (!roleIds.isEmpty()) { - return getFilteredRoleIds(roleIds, appId, authenticatedUser.getTenantDomain()); - } - return new ArrayList<>(); + return roleIds; } /** - * Get the filtered role ids. - * - * @param roleId Role id list. - * @param appId App id. - * @param tenantDomain Tenant domain. - * @return Filtered role ids. - * @throws ScopeValidationHandlerException if an error occurs while retrieving filtered role id list. - */ - private List getFilteredRoleIds(List roleId, String appId, String tenantDomain) - throws ScopeValidationHandlerException { - - List rolesAssociatedWithApp = getRoleIdsAssociatedWithApp(appId, tenantDomain); - return roleId.stream().distinct().filter(rolesAssociatedWithApp::contains).collect(Collectors.toList()); - } - - /** - * Get the role ids associated with app. + * Get the associated scopes for the roles. * - * @param appId App id. + * @param roles Roles. * @param tenantDomain Tenant domain. - * @return Role ids associated with app. - * @throws ScopeValidationHandlerException if an error occurs while retrieving role id list of app. + * @return List of associated scopes. + * @throws IdentityOAuth2Exception if an error occurs while retrieving scope list of roles. */ - private List getRoleIdsAssociatedWithApp(String appId, String tenantDomain) - throws ScopeValidationHandlerException { + public static List getAssociatedScopesForRoles(List roles, String tenantDomain) + throws IdentityOAuth2Exception { try { - return OAuth2ServiceComponentHolder.getApplicationMgtService() - .getAssociatedRolesOfApplication(appId, tenantDomain).stream().map(RoleV2::getId) - .collect(Collectors.toCollection(ArrayList::new)); - } catch (IdentityApplicationManagementException e) { - throw new ScopeValidationHandlerException("Error while retrieving role id list of app : " + appId - + "tenant domain : " + tenantDomain, e); + return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() + .getPermissionListOfRoles(roles, tenantDomain); + } catch (IdentityRoleManagementException e) { + throw new IdentityOAuth2Exception("Error while retrieving scope list of roles : " + + StringUtils.join(roles, ",") + "tenant domain : " + tenantDomain, e); } } @@ -175,55 +105,35 @@ private List getRoleIdsAssociatedWithApp(String appId, String tenantDoma * @param userId User id. * @param tenantDomain Tenant domain. * @return Role ids of user. - * @throws ScopeValidationHandlerException if an error occurs while retrieving role id list of user. + * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of user. */ - private List getRoleIdsOfUser(String userId, String tenantDomain) throws ScopeValidationHandlerException { + private static List getRoleIdsOfUser(String userId, String tenantDomain) throws IdentityOAuth2Exception { try { return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() .getRoleIdListOfUser(userId, tenantDomain); } catch (IdentityRoleManagementException e) { - throw new ScopeValidationHandlerException("Error while retrieving role id list of user : " + userId + throw new IdentityOAuth2Exception("Error while retrieving role id list of user : " + userId + "tenant domain : " + tenantDomain, e); } } - /** - * Get the role ids of groups. - * - * @param groups Groups. - * @param tenantDomain Tenant domain. - * @return Role ids of groups. - * @throws ScopeValidationHandlerException if an error occurs while retrieving role id list of groups. - */ - private List getRoleIdsOfGroups(List groups, String tenantDomain) - throws ScopeValidationHandlerException { - - try { - return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() - .getRoleIdListOfGroups(groups, tenantDomain); - } catch (IdentityRoleManagementException e) { - throw new ScopeValidationHandlerException("Error while retrieving role id list of groups : " - + StringUtils.join(groups, ",") + "tenant domain : " + tenantDomain, e); - } - } - /** * Get the role ids of idp groups * * @param groups Groups. * @param tenantDomain Tenant domain. * @return Role ids of idp groups. - * @throws ScopeValidationHandlerException if an error occurs while retrieving role id list of idp groups. + * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of idp groups. */ - private List getRoleIdsOfIdpGroups(List groups, String tenantDomain) - throws ScopeValidationHandlerException { + private static List getRoleIdsOfIdpGroups(List groups, String tenantDomain) + throws IdentityOAuth2Exception { try { return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() .getRoleIdListOfIdpGroups(groups, tenantDomain); } catch (IdentityRoleManagementException e) { - throw new ScopeValidationHandlerException("Error while retrieving role id list of groups : " + throw new IdentityOAuth2Exception("Error while retrieving role id list of groups : " + StringUtils.join(groups, ",") + "tenant domain : " + tenantDomain, e); } } @@ -234,8 +144,8 @@ private List getRoleIdsOfIdpGroups(List groups, String tenantDom * @param authenticatedUser Authenticated user. * @return - Groups of the user. */ - private List getUserGroups(AuthenticatedUser authenticatedUser) - throws ScopeValidationHandlerException { + private static List getUserGroups(AuthenticatedUser authenticatedUser) + throws IdentityOAuth2Exception { if (LOG.isDebugEnabled()) { LOG.debug("Started group fetching for scope validation."); @@ -257,12 +167,12 @@ private List getUserGroups(AuthenticatedUser authenticatedUser) } } } catch (UserIdNotFoundException | IdentityOAuth2Exception e) { - throw new ScopeValidationHandlerException(e.getMessage(), e); + throw new IdentityOAuth2Exception(e.getMessage(), e); } catch (UserStoreException e) { if (isDoGetGroupListOfUserNotImplemented(e)) { return userGroups; } - throw new ScopeValidationHandlerException(e.getMessage(), e); + throw new IdentityOAuth2Exception(e.getMessage(), e); } if (LOG.isDebugEnabled()) { LOG.debug("Completed group fetching for scope validation."); @@ -276,8 +186,8 @@ private List getUserGroups(AuthenticatedUser authenticatedUser) * @param authenticatedUser Authenticated user. * @return - Groups of the user. */ - private List getUserIdpGroups(AuthenticatedUser authenticatedUser) - throws ScopeValidationHandlerException { + private static List getUserIdpGroups(AuthenticatedUser authenticatedUser) + throws IdentityOAuth2Exception { if (LOG.isDebugEnabled()) { LOG.debug("Started group fetching for scope validation."); @@ -324,15 +234,35 @@ private List getUserIdpGroups(AuthenticatedUser authenticatedUser) * @param idpName Identity provider name. * @param tenantDomain Tenant domain. * @return Identity Provider object. - * @throws ScopeValidationHandlerException Exception thrown when getting the identity provider. + * @throws IdentityOAuth2Exception Exception thrown when getting the identity provider. */ - private IdentityProvider getIdentityProvider(String idpName, String tenantDomain) - throws ScopeValidationHandlerException { + private static IdentityProvider getIdentityProvider(String idpName, String tenantDomain) + throws IdentityOAuth2Exception { try { return OAuth2ServiceComponentHolder.getInstance().getIdpManager().getIdPByName(idpName, tenantDomain); } catch (IdentityProviderManagementException e) { - throw new ScopeValidationHandlerException("Error while retrieving idp by idp name : " + idpName, e); + throw new IdentityOAuth2Exception("Error while retrieving idp by idp name : " + idpName, e); + } + } + + /** + * Get the role ids of groups. + * + * @param groups Groups. + * @param tenantDomain Tenant domain. + * @return Role ids of groups. + * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of groups. + */ + private static List getRoleIdsOfGroups(List groups, String tenantDomain) + throws IdentityOAuth2Exception { + + try { + return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() + .getRoleIdListOfGroups(groups, tenantDomain); + } catch (IdentityRoleManagementException e) { + throw new IdentityOAuth2Exception("Error while retrieving role id list of groups : " + + StringUtils.join(groups, ",") + "tenant domain : " + tenantDomain, e); } } @@ -344,7 +274,7 @@ private IdentityProvider getIdentityProvider(String idpName, String tenantDomain * @return true if the UserStoreException was caused by the doGetGroupListOfUser method not being implemented, * false otherwise. */ - private boolean isDoGetGroupListOfUserNotImplemented(UserStoreException e) { + private static boolean isDoGetGroupListOfUserNotImplemented(UserStoreException e) { Throwable cause = e.getCause(); while (cause != null) { @@ -355,16 +285,4 @@ private boolean isDoGetGroupListOfUserNotImplemented(UserStoreException e) { } return false; } - - @Override - public String getPolicyID() { - - return "RBAC"; - } - - @Override - public String getName() { - - return "RoleBasedScopeValidationHandler"; - } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index eeb71b8f3be..f30c58f9f89 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -17,9 +17,9 @@ import org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationContext; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandlerException; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationContext; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandlerException; import java.util.ArrayList; import java.util.Arrays; @@ -42,6 +42,8 @@ public class DefaultOAuth2ScopeValidator { private static final Log LOG = LogFactory.getLog(DefaultOAuth2ScopeValidator.class); + private static final String NO_POLICY_HANDLER = "NoPolicyScopeValidationHandler"; + /** * Validate scope. * @@ -153,13 +155,14 @@ private List getAuthorizedScopes(List requestedScopes, Authentic } } - // If "NoPolicy" exists, add all its scopes to the result - Set scopes = new HashSet<>(validatedScopesByHandler.getOrDefault("NoPolicyScopeValidationHandler", + // If "NoPolicyScopeValidationHandler" exists, add all its scopes to the result + Set scopes = new HashSet<>(validatedScopesByHandler.getOrDefault(NO_POLICY_HANDLER, Collections.emptyList())); - // Separate "NoPolicy" and get the intersection of the rest of the scopes validated by other validators + // Separate "NoPolicyScopeValidationHandler" and get the intersection of the rest of the scopes validated + // by other validators List> otherHandlerScopes = new ArrayList<>(validatedScopesByHandler.values()); - otherHandlerScopes.remove(validatedScopesByHandler.get("NoPolicyScopeValidationHandler")); + otherHandlerScopes.remove(validatedScopesByHandler.get(NO_POLICY_HANDLER)); List intersection = new ArrayList<>(); if (!otherHandlerScopes.isEmpty()) { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationContext.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationContext.java similarity index 97% rename from components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationContext.java rename to components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationContext.java index 0ce2490a65a..14f93c2479d 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationContext.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationContext.java @@ -1,4 +1,4 @@ -package org.wso2.carbon.identity.oauth2.validators.policyhandler; +package org.wso2.carbon.identity.oauth2.validators.validationhandler; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandler.java similarity index 94% rename from components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java rename to components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandler.java index 2423343d757..96f5ce3f10a 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandler.java @@ -1,4 +1,4 @@ -package org.wso2.carbon.identity.oauth2.validators.policyhandler; +package org.wso2.carbon.identity.oauth2.validators.validationhandler; import java.util.List; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandlerException.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandlerException.java similarity index 89% rename from components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandlerException.java rename to components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandlerException.java index 9566b69e3f4..ca6b6aec11f 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/ScopeValidationHandlerException.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandlerException.java @@ -1,4 +1,4 @@ -package org.wso2.carbon.identity.oauth2.validators.policyhandler; +package org.wso2.carbon.identity.oauth2.validators.validationhandler; /** * ScopeValidatorPolicyHandlerException diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java similarity index 74% rename from components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java rename to components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java index f82357952a0..f5337d0a6e9 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/M2MScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java @@ -1,9 +1,9 @@ -package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; +package org.wso2.carbon.identity.oauth2.validators.validationhandler.impl; import org.wso2.carbon.identity.oauth.common.OAuthConstants; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationContext; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandlerException; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationContext; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandlerException; import java.util.List; import java.util.stream.Collectors; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/NoPolicyScopeValidationHandler.java similarity index 71% rename from components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java rename to components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/NoPolicyScopeValidationHandler.java index 48f3299aa4b..842531e6de2 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/policyhandler/impl/NoPolicyScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/NoPolicyScopeValidationHandler.java @@ -1,8 +1,8 @@ -package org.wso2.carbon.identity.oauth2.validators.policyhandler.impl; +package org.wso2.carbon.identity.oauth2.validators.validationhandler.impl; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationContext; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandler; -import org.wso2.carbon.identity.oauth2.validators.policyhandler.ScopeValidationHandlerException; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationContext; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandlerException; import java.util.List; import java.util.stream.Collectors; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java new file mode 100644 index 00000000000..78b95dbeffc --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java @@ -0,0 +1,108 @@ +package org.wso2.carbon.identity.oauth2.validators.validationhandler.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException; +import org.wso2.carbon.identity.application.common.model.RoleV2; +import org.wso2.carbon.identity.oauth.common.OAuthConstants; +import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; +import org.wso2.carbon.identity.oauth2.util.AuthzUtil; +import org.wso2.carbon.identity.oauth2.validators.DefaultOAuth2ScopeValidator; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationContext; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandler; +import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandlerException; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * RoleBasedScopeValidationHandler + */ +public class RoleBasedScopeValidationHandler implements ScopeValidationHandler { + + private static final Log LOG = LogFactory.getLog(DefaultOAuth2ScopeValidator.class); + + @Override + public boolean canHandle(ScopeValidationContext scopeValidationContext) { + + return getPolicyID().equals(scopeValidationContext.getPolicyId()) + && !OAuthConstants.GrantTypes.CLIENT_CREDENTIALS.equals(scopeValidationContext.getGrantType()); + } + + @Override + public List validateScopes(List requestedScopes, List appAuthorizedScopes, + ScopeValidationContext scopeValidationContext) + throws ScopeValidationHandlerException { + + try { + List userRoles = AuthzUtil.getUserRoles(scopeValidationContext.getAuthenticatedUser()); + if (userRoles.isEmpty()) { + return new ArrayList<>(); + } + List filteredRoleIds = getFilteredRoleIds(userRoles, scopeValidationContext.getAppId(), + scopeValidationContext.getAuthenticatedUser().getTenantDomain()); + if (filteredRoleIds.isEmpty()) { + return new ArrayList<>(); + } + List associatedScopes = AuthzUtil.getAssociatedScopesForRoles(filteredRoleIds, + scopeValidationContext.getAuthenticatedUser().getTenantDomain()); + List filteredScopes = appAuthorizedScopes.stream().filter(associatedScopes::contains) + .collect(Collectors.toList()); + return requestedScopes.stream().filter(filteredScopes::contains).collect(Collectors.toList()); + } catch (IdentityOAuth2Exception e) { + throw new ScopeValidationHandlerException("Error while validation scope with RBAC Scope Validation " + + "handler", e); + } + } + + /** + * Get the filtered role ids. + * + * @param roleId Role id list. + * @param appId App id. + * @param tenantDomain Tenant domain. + * @return Filtered role ids. + * @throws ScopeValidationHandlerException if an error occurs while retrieving filtered role id list. + */ + private List getFilteredRoleIds(List roleId, String appId, String tenantDomain) + throws ScopeValidationHandlerException { + + List rolesAssociatedWithApp = getRoleIdsAssociatedWithApp(appId, tenantDomain); + return roleId.stream().distinct().filter(rolesAssociatedWithApp::contains).collect(Collectors.toList()); + } + + /** + * Get the role ids associated with app. + * + * @param appId App id. + * @param tenantDomain Tenant domain. + * @return Role ids associated with app. + * @throws ScopeValidationHandlerException if an error occurs while retrieving role id list of app. + */ + private List getRoleIdsAssociatedWithApp(String appId, String tenantDomain) + throws ScopeValidationHandlerException { + + try { + return OAuth2ServiceComponentHolder.getApplicationMgtService() + .getAssociatedRolesOfApplication(appId, tenantDomain).stream().map(RoleV2::getId) + .collect(Collectors.toCollection(ArrayList::new)); + } catch (IdentityApplicationManagementException e) { + throw new ScopeValidationHandlerException("Error while retrieving role id list of app : " + appId + + "tenant domain : " + tenantDomain, e); + } + } + + @Override + public String getPolicyID() { + + return "RBAC"; + } + + @Override + public String getName() { + + return "RoleBasedScopeValidationHandler"; + } +} From 1df355203be945552c3ba0ca0ec928fd74b2fea7 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Tue, 24 Oct 2023 18:12:00 +0530 Subject: [PATCH 17/29] move legacy check to authzutil --- .../oauth2/authz/AuthorizationHandlerManager.java | 5 +++-- .../identity/oauth2/token/AccessTokenIssuer.java | 7 ++++--- .../wso2/carbon/identity/oauth2/util/AuthzUtil.java | 11 +++++++++++ .../wso2/carbon/identity/oauth2/util/OAuth2Util.java | 11 ----------- .../carbon/identity/oauth2/util/Oauth2ScopeUtils.java | 3 ++- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java index aa2c64a252c..9c2fce935b3 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java @@ -41,6 +41,7 @@ import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeReqDTO; import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeRespDTO; import org.wso2.carbon.identity.oauth2.model.OAuth2Parameters; +import org.wso2.carbon.identity.oauth2.util.AuthzUtil; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.identity.oauth2.validators.DefaultOAuth2ScopeValidator; import org.wso2.carbon.identity.oauth2.validators.JDBCPermissionBasedInternalScopeValidator; @@ -278,7 +279,7 @@ private void validateRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, // Remove the system level allowed scopes from requested scopes for further validation. removeAllowedScopesFromRequestedScopes(authzReqMsgCtx, requestedAllowedScopes); List authorizedScopes = null; - if (OAuth2Util.isLegacyAuthzRuntime()) { + if (AuthzUtil.isLegacyAuthzRuntime()) { // If it is management app, we validate internal scopes in the requested scopes. String[] authorizedInternalScopes = new String[0]; log.debug("Handling the internal scope validation."); @@ -304,7 +305,7 @@ private void validateRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, boolean isValid = validateScopes(authzReqMsgCtx, authzHandler); boolean isValidatedScopesContainsInRequestedScopes = isValidatedScopesContainsInRequestedScopes(authzReqMsgCtx); if (isValid && isValidatedScopesContainsInRequestedScopes) { - if (OAuth2Util.isLegacyAuthzRuntime()) { + if (AuthzUtil.isLegacyAuthzRuntime()) { // Add authorized internal scopes to the request for sending in the response. addAuthorizedInternalScopes(authzReqMsgCtx, authzReqMsgCtx.getAuthorizedInternalScopes()); } else { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java index aab515cbd0d..59cd6bd0832 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java @@ -66,6 +66,7 @@ import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinding; import org.wso2.carbon.identity.oauth2.token.handlers.grant.AuthorizationGrantHandler; import org.wso2.carbon.identity.oauth2.token.handlers.response.AccessTokenResponseHandler; +import org.wso2.carbon.identity.oauth2.util.AuthzUtil; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.identity.oauth2.validators.DefaultOAuth2ScopeValidator; import org.wso2.carbon.identity.oauth2.validators.JDBCPermissionBasedInternalScopeValidator; @@ -678,7 +679,7 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I if (log.isDebugEnabled()) { log.debug("Handling the internal scope validation."); } - if (OAuth2Util.isLegacyAuthzRuntime()) { + if (AuthzUtil.isLegacyAuthzRuntime()) { // Execute Internal SCOPE Validation. JDBCPermissionBasedInternalScopeValidator scopeValidator = new JDBCPermissionBasedInternalScopeValidator(); @@ -715,7 +716,7 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I Those scopes should not send to the other scopes validators. Thus remove the scopes from the tokReqMsgCtx. Will be added to the response after executing the other scope validators. */ - if (OAuth2Util.isLegacyAuthzRuntime()) { + if (AuthzUtil.isLegacyAuthzRuntime()) { removeInternalScopes(tokReqMsgCtx); // Adding the authorized internal scopes to tokReqMsgCtx for any special validators to use. @@ -740,7 +741,7 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I boolean isValidScope = authzGrantHandler.validateScope(tokReqMsgCtx); if (isValidScope) { // Add authorized internal scopes to the request for sending in the response. - if (OAuth2Util.isLegacyAuthzRuntime()) { + if (AuthzUtil.isLegacyAuthzRuntime()) { addAuthorizedInternalScopes(tokReqMsgCtx, tokReqMsgCtx.getAuthorizedInternalScopes()); } else { addAuthorizedScopes(tokReqMsgCtx, authorizedScopes); diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java index 9d585417448..f098e31bbb0 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java @@ -3,6 +3,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; @@ -285,4 +286,14 @@ private static boolean isDoGetGroupListOfUserNotImplemented(UserStoreException e } return false; } + + /** + * Check whether legacy authroization runtime is enabled. + * + * @return True if legacy authroization runtime is enabled. + */ + public static boolean isLegacyAuthzRuntime() { + + return CarbonConstants.ENABLE_LEGACY_AUTHZ_RUNTIME; + } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java index c4100c0097e..c03f9a10931 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java @@ -63,7 +63,6 @@ import org.apache.oltu.oauth2.common.utils.OAuthUtils; import org.json.JSONException; import org.json.JSONObject; -import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.core.util.KeyStoreManager; import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; @@ -4987,16 +4986,6 @@ public static String[] extractCredentialsFromAuthzHeader(HttpServletRequest requ return OAuthUtils.decodeClientAuthenticationHeader(authorizationHeader); } - - /** - * Check whether legacy authroization runtime is enabled. - * - * @return True if legacy authroization runtime is enabled. - */ - public static boolean isLegacyAuthzRuntime() { - - return CarbonConstants.ENABLE_LEGACY_AUTHZ_RUNTIME; - } /** * Retrieve the list of client authentication methods supported by the server. diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java index c9aede1d8c1..3fa652cd1b5 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java @@ -55,6 +55,7 @@ public class Oauth2ScopeUtils { public static final String OAUTH_APP_DO_PROPERTY_NAME = "OAuthAppDO"; private static final String OAUTH_ENABLE_SYSTEM_LEVEL_INTERNAL_SYSTEM_SCOPE_MANAGEMENT = "OAuth.EnableSystemLevelInternalSystemScopeManagement"; + private static final String LEGACY_RBAC_SCOPE_VALIDATOR = "Role based scope validator"; public static IdentityOAuth2ScopeServerException generateServerException(Oauth2ScopeConstants.ErrorMessages error, String data) @@ -260,7 +261,7 @@ private static boolean iterateOAuth2ScopeValidators(OAuthAuthzReqMessageContext // Iterate through all available scope validators. for (OAuth2ScopeValidator validator : oAuth2ScopeValidators) { - if (!OAuth2Util.isLegacyAuthzRuntime() && "Role based scope validator".equals(validator + if (!AuthzUtil.isLegacyAuthzRuntime() && LEGACY_RBAC_SCOPE_VALIDATOR.equals(validator .getValidatorName())) { return true; } From 3c1b5ded312d428b9f429e26df5a20b5fa61b371 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Tue, 24 Oct 2023 20:23:36 +0530 Subject: [PATCH 18/29] add licence headers --- .../authz/AuthorizationHandlerManager.java | 1 + .../internal/OAuth2ServiceComponent.java | 22 +++++++++++++++++++ .../OAuth2ServiceComponentHolder.java | 1 - .../oauth2/token/AccessTokenIssuer.java | 1 + .../identity/oauth2/util/AuthzUtil.java | 20 ++++++++++++++++- .../DefaultOAuth2ScopeValidator.java | 20 ++++++++++++++++- .../ScopeValidationContext.java | 20 ++++++++++++++++- .../ScopeValidationHandler.java | 20 ++++++++++++++++- .../ScopeValidationHandlerException.java | 18 +++++++++++++++ .../impl/M2MScopeValidationHandler.java | 22 +++++++++++++++++-- .../impl/NoPolicyScopeValidationHandler.java | 20 ++++++++++++++++- .../impl/RoleBasedScopeValidationHandler.java | 20 ++++++++++++++++- 12 files changed, 176 insertions(+), 9 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java index 9c2fce935b3..6e111c5fe2a 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java @@ -279,6 +279,7 @@ private void validateRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, // Remove the system level allowed scopes from requested scopes for further validation. removeAllowedScopesFromRequestedScopes(authzReqMsgCtx, requestedAllowedScopes); List authorizedScopes = null; + // Switch the scope validators dynamically based on the authorization runtime. if (AuthzUtil.isLegacyAuthzRuntime()) { // If it is management app, we validate internal scopes in the requested scopes. String[] authorizedInternalScopes = new String[0]; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java index 62a59f9c984..a60bc64c9bf 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java @@ -1231,12 +1231,20 @@ protected void unsetRealmService(RealmService realmService) { ) protected void setAuthorizedAPIManagementService(AuthorizedAPIManagementService authorizedAPIManagementService) { + if (log.isDebugEnabled()) { + log.debug("Adding Authorized API Management Service: " + authorizedAPIManagementService.getClass() + .getName()); + } OAuth2ServiceComponentHolder.getInstance() .setAuthorizedAPIManagementService(authorizedAPIManagementService); } protected void unsetAuthorizedAPIManagementService(AuthorizedAPIManagementService authorizedAPIManagementService) { + if (log.isDebugEnabled()) { + log.debug("Removing Authorized API Management Service: " + authorizedAPIManagementService.getClass() + .getName()); + } OAuth2ServiceComponentHolder.getInstance().setAuthorizedAPIManagementService(null); } @@ -1248,9 +1256,17 @@ protected void unsetAuthorizedAPIManagementService(AuthorizedAPIManagementServic unbind = "unsetAPIResourceManagerService" ) protected void setAPIResourceManagerService(APIResourceManager apiResourceManager) { + + if (log.isDebugEnabled()) { + log.debug("Adding API Resource Manager: " + apiResourceManager.getClass().getName()); + } OAuth2ServiceComponentHolder.getInstance().setApiResourceManager(apiResourceManager); } protected void unsetAPIResourceManagerService(APIResourceManager apiResourceManager) { + + if (log.isDebugEnabled()) { + log.debug("Removing API Resource Manager: " + apiResourceManager.getClass().getName()); + } OAuth2ServiceComponentHolder.getInstance().setApiResourceManager(null); } @@ -1267,6 +1283,9 @@ protected void unsetAPIResourceManagerService(APIResourceManager apiResourceMana unbind = "unsetRoleManagementServiceV2") protected void setRoleManagementServiceV2(RoleManagementService roleManagementService) { + if (log.isDebugEnabled()) { + log.debug("Adding Role Management Service V2: " + roleManagementService.getClass().getName()); + } OAuth2ServiceComponentHolder.getInstance().setRoleManagementServiceV2(roleManagementService); } @@ -1277,6 +1296,9 @@ protected void setRoleManagementServiceV2(RoleManagementService roleManagementSe */ protected void unsetRoleManagementServiceV2(RoleManagementService roleManagementService) { + if (log.isDebugEnabled()) { + log.debug("Removing Role Management Service V2: " + roleManagementService.getClass().getName()); + } OAuth2ServiceComponentHolder.getInstance().setRoleManagementServiceV2(null); } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java index 13dd877a98d..9f5ae076394 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java @@ -104,7 +104,6 @@ public class OAuth2ServiceComponentHolder { private boolean isOrganizationManagementEnabled = false; private RefreshTokenGrantProcessor refreshTokenGrantProcessor; private OAuth2RevocationProcessor revocationProcessor; - private AuthorizedAPIManagementService authorizedAPIManagementService; private APIResourceManager apiResourceManager; private RoleManagementService roleManagementServiceV2; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java index 59cd6bd0832..5c1abf694f4 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java @@ -679,6 +679,7 @@ private boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws I if (log.isDebugEnabled()) { log.debug("Handling the internal scope validation."); } + // Switch the scope validators dynamically based on the authorization runtime. if (AuthzUtil.isLegacyAuthzRuntime()) { // Execute Internal SCOPE Validation. JDBCPermissionBasedInternalScopeValidator scopeValidator = diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java index f098e31bbb0..bc679a804d4 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.wso2.carbon.identity.oauth2.util; import org.apache.commons.lang.StringUtils; @@ -35,7 +53,7 @@ import static org.wso2.carbon.user.core.UserCoreConstants.INTERNAL_DOMAIN; /** - * AuthzUtil + * Utility methods for the authorization related functionality. */ public class AuthzUtil { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index f30c58f9f89..1aa1ec65c1b 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.wso2.carbon.identity.oauth2.validators; import org.apache.commons.lang.ArrayUtils; @@ -34,7 +52,7 @@ import static org.wso2.carbon.identity.oauth2.Oauth2ScopeConstants.SYSTEM_SCOPE; /** - * DefaultOAuth2ScopeValidator + * Default oauth2 scope validator which validate application authorized scopes. */ public class DefaultOAuth2ScopeValidator { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationContext.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationContext.java index 14f93c2479d..b7736493c1f 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationContext.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationContext.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.wso2.carbon.identity.oauth2.validators.validationhandler; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; @@ -6,7 +24,7 @@ import java.util.Map; /** - * PolicyContext + * Scope Validation Context is where we pass scope validation context to the scope validation handlers. */ public class ScopeValidationContext { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandler.java index 96f5ce3f10a..7ab73cdfc0d 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandler.java @@ -1,9 +1,27 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.wso2.carbon.identity.oauth2.validators.validationhandler; import java.util.List; /** - * ScopeValidatorPolicyHandler + * Each scope validation handler for authorized policies should implement this. */ public interface ScopeValidationHandler { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandlerException.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandlerException.java index ca6b6aec11f..ad5411cacb5 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandlerException.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/ScopeValidationHandlerException.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.wso2.carbon.identity.oauth2.validators.validationhandler; /** diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java index f5337d0a6e9..389a256c993 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.wso2.carbon.identity.oauth2.validators.validationhandler.impl; import org.wso2.carbon.identity.oauth.common.OAuthConstants; @@ -9,7 +27,7 @@ import java.util.stream.Collectors; /** - * M2MScopeValidationHandler + * M2M scope validation handler engage for client credential grant to validate scopes. */ public class M2MScopeValidationHandler implements ScopeValidationHandler { @@ -17,7 +35,7 @@ public class M2MScopeValidationHandler implements ScopeValidationHandler { public boolean canHandle(ScopeValidationContext scopeValidationContext) { return OAuthConstants.GrantTypes.CLIENT_CREDENTIALS.equals(scopeValidationContext.getGrantType()) && - !getPolicyID().equals("NoPolicy"); + getPolicyID().equals("RBAC"); } @Override diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/NoPolicyScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/NoPolicyScopeValidationHandler.java index 842531e6de2..48a38407a8b 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/NoPolicyScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/NoPolicyScopeValidationHandler.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.wso2.carbon.identity.oauth2.validators.validationhandler.impl; import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationContext; @@ -8,7 +26,7 @@ import java.util.stream.Collectors; /** - * NoPolicyPolicyHandler + * No policy scope validation handler handle authorized no policy scopes. */ public class NoPolicyScopeValidationHandler implements ScopeValidationHandler { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java index 78b95dbeffc..b0afda95f2b 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.wso2.carbon.identity.oauth2.validators.validationhandler.impl; import org.apache.commons.logging.Log; @@ -18,7 +36,7 @@ import java.util.stream.Collectors; /** - * RoleBasedScopeValidationHandler + * Role based scope validation handler validate scopes based on users roles. */ public class RoleBasedScopeValidationHandler implements ScopeValidationHandler { From e9d52c8666173b14d0ce963be0ea12849a526408 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 25 Oct 2023 02:15:14 +0530 Subject: [PATCH 19/29] fix for asub org user --- .../identity/oauth2/util/AuthzUtil.java | 60 ++++++++++++++----- .../DefaultOAuth2ScopeValidator.java | 16 ++--- 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java index bc679a804d4..0d368b74834 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java @@ -29,8 +29,10 @@ import org.wso2.carbon.identity.application.common.model.ClaimMapping; import org.wso2.carbon.identity.application.common.model.IdPGroup; import org.wso2.carbon.identity.application.common.model.IdentityProvider; +import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; +import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementException; import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; import org.wso2.carbon.user.api.UserStoreException; @@ -71,14 +73,9 @@ public static List getUserRoles(AuthenticatedUser authenticatedUser) List roleIds = new ArrayList<>(); // Get role id list of the user. - try { - List roleIdsOfUser = getRoleIdsOfUser(authenticatedUser.getUserId(), - authenticatedUser.getTenantDomain()); - if (!roleIdsOfUser.isEmpty()) { - roleIds.addAll(roleIdsOfUser); - } - } catch (UserIdNotFoundException e) { - throw new IdentityOAuth2Exception("Error while resolving user id of user", e); + List roleIdsOfUser = getRoleIdsOfUser(authenticatedUser); + if (!roleIdsOfUser.isEmpty()) { + roleIds.addAll(roleIdsOfUser); } // Get groups of the user. List groups = getUserGroups(authenticatedUser); @@ -118,6 +115,42 @@ public static List getAssociatedScopesForRoles(List roles, Strin } } + /** + * Get the role ids of user. + * + * @param authenticatedUser AuthenticatedUser. + * @return Role ids of user. + * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of user. + */ + private static List getRoleIdsOfUser(AuthenticatedUser authenticatedUser) throws IdentityOAuth2Exception { + + String tenantDomain = authenticatedUser.getTenantDomain(); + if (authenticatedUser.getAccessingOrganization() != null) { + try { + tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager() + .resolveTenantDomain(authenticatedUser.getUserResidentOrganization()); + } catch (OrganizationManagementException e) { + throw new RuntimeException(e); + } + } + String userId; + try { + userId = authenticatedUser.getUserId(); + } catch (UserIdNotFoundException e) { + throw new IdentityOAuth2Exception("Error while resolving user id of user" , e); + } + if (userId == null) { + throw new IdentityOAuth2Exception("user not found"); + } + try { + return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() + .getRoleIdListOfUser(userId, tenantDomain); + } catch (IdentityRoleManagementException e) { + throw new IdentityOAuth2Exception("Error while retrieving role id list of user : " + userId + + "tenant domain : " + tenantDomain, e); + } + } + /** * Get the role ids of user. * @@ -126,7 +159,7 @@ public static List getAssociatedScopesForRoles(List roles, Strin * @return Role ids of user. * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of user. */ - private static List getRoleIdsOfUser(String userId, String tenantDomain) throws IdentityOAuth2Exception { + private static List getRoleIdsOfUser2(String userId, String tenantDomain) throws IdentityOAuth2Exception { try { return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() @@ -208,9 +241,8 @@ private static List getUserGroups(AuthenticatedUser authenticatedUser) private static List getUserIdpGroups(AuthenticatedUser authenticatedUser) throws IdentityOAuth2Exception { - if (LOG.isDebugEnabled()) { - LOG.debug("Started group fetching for scope validation."); - } + LOG.debug("Started group fetching for scope validation."); + String idpName = authenticatedUser.getFederatedIdPName(); String tenantDomain = authenticatedUser.getTenantDomain(); IdentityProvider federatedIdP = getIdentityProvider(idpName, tenantDomain); @@ -306,9 +338,9 @@ private static boolean isDoGetGroupListOfUserNotImplemented(UserStoreException e } /** - * Check whether legacy authroization runtime is enabled. + * Check whether legacy authorization runtime is enabled. * - * @return True if legacy authroization runtime is enabled. + * @return True if legacy authorization runtime is enabled. */ public static boolean isLegacyAuthzRuntime() { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index 1aa1ec65c1b..334bfbfa1c6 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -152,18 +152,18 @@ private List getAuthorizedScopes(List requestedScopes, Authentic Map> validatedScopesByHandler = new HashMap<>(); for (AuthorizedScopes authorizedScopes : authorizedScopesList) { String policyId = authorizedScopes.getPolicyId(); - ScopeValidationContext policyContext = new ScopeValidationContext(); - policyContext.setAuthenticatedUser(authenticatedUser); - policyContext.setAppId(appId); - policyContext.setPolicyId(policyId); - policyContext.setGrantType(grantType); + ScopeValidationContext scopeValidationContext = new ScopeValidationContext(); + scopeValidationContext.setAuthenticatedUser(authenticatedUser); + scopeValidationContext.setAppId(appId); + scopeValidationContext.setPolicyId(policyId); + scopeValidationContext.setGrantType(grantType); for (ScopeValidationHandler scopeValidationHandler : scopeValidationHandlers) { - if (scopeValidationHandler.canHandle(policyContext)) { - policyContext.setValidatedScopesByHandler(validatedScopesByHandler); + if (scopeValidationHandler.canHandle(scopeValidationContext)) { + scopeValidationContext.setValidatedScopesByHandler(validatedScopesByHandler); List validatedScopes; try { validatedScopes = scopeValidationHandler.validateScopes(requestedScopes, - authorizedScopes.getScopes(), policyContext); + authorizedScopes.getScopes(), scopeValidationContext); } catch (ScopeValidationHandlerException e) { throw new IdentityOAuth2Exception("Error while validating policies roles from " + "authorization service.", e); From 213219cde45b7225ec0c3853a4990898de56635f Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 25 Oct 2023 02:46:56 +0530 Subject: [PATCH 20/29] fix kernel version --- .../OAuth2ServiceComponentHolder.java | 28 ++++++++++++++++++- pom.xml | 4 +-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java index 13dd877a98d..fde082095a8 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java @@ -30,6 +30,8 @@ import org.wso2.carbon.identity.event.services.IdentityEventService; import org.wso2.carbon.identity.oauth.OAuthAdminServiceImpl; import org.wso2.carbon.identity.oauth.dto.ScopeDTO; +import org.wso2.carbon.identity.oauth.tokenprocessor.AccessTokenProvider; +import org.wso2.carbon.identity.oauth.tokenprocessor.DefaultAccessTokenProvider; import org.wso2.carbon.identity.oauth.tokenprocessor.DefaultOAuth2RevocationProcessor; import org.wso2.carbon.identity.oauth.tokenprocessor.DefaultRefreshTokenGrantProcessor; import org.wso2.carbon.identity.oauth.tokenprocessor.OAuth2RevocationProcessor; @@ -104,7 +106,7 @@ public class OAuth2ServiceComponentHolder { private boolean isOrganizationManagementEnabled = false; private RefreshTokenGrantProcessor refreshTokenGrantProcessor; private OAuth2RevocationProcessor revocationProcessor; - + private AccessTokenProvider accessTokenProvider; private AuthorizedAPIManagementService authorizedAPIManagementService; private APIResourceManager apiResourceManager; private RoleManagementService roleManagementServiceV2; @@ -720,6 +722,30 @@ public void removeAuthorizationRequestBuilder(OAuthAuthorizationRequestBuilder o oAuthAuthorizationRequestBuilders.remove(oAuthAuthorizationRequestBuilder); } + /** + * Get access token provider. + * + * @return AccessTokenProvider + */ + public AccessTokenProvider getAccessTokenProvider() { + + if (accessTokenProvider == null) { + accessTokenProvider = new DefaultAccessTokenProvider(); + } + return accessTokenProvider; + } + + /** + * Set access token provider. + * + * @param accessTokenProvider AccessTokenProvider + */ + public void setAccessTokenProvider(AccessTokenProvider accessTokenProvider) { + + this.accessTokenProvider = accessTokenProvider; + } + + public AuthorizedAPIManagementService getAuthorizedAPIManagementService() { return authorizedAPIManagementService; diff --git a/pom.xml b/pom.xml index 7c1fa76ca87..ef7707e7c41 100644 --- a/pom.xml +++ b/pom.xml @@ -866,13 +866,13 @@ 1.2.4 - 4.9.10 + 4.9.16 4.9.7 [4.5.0, 5.0.0) [1.0.1, 2.0.0) - 5.25.427 + 5.25.434 [5.25.234, 7.0.0) From 2f94647f6b7609a51683deb40077ac66a381c594 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 25 Oct 2023 09:46:29 +0530 Subject: [PATCH 21/29] fix compile issue wth fasterxml --- .../identity/oauth2/model/AccessTokenExtendedAttributes.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/model/AccessTokenExtendedAttributes.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/model/AccessTokenExtendedAttributes.java index 0b13bdf76e5..7e6854e1733 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/model/AccessTokenExtendedAttributes.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/model/AccessTokenExtendedAttributes.java @@ -18,8 +18,8 @@ package org.wso2.carbon.identity.oauth2.model; -import com.hazelcast.com.fasterxml.jackson.annotation.JsonIgnore; -import com.hazelcast.com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.io.Serializable; import java.util.Map; From 02b537cf2ad56b98c036f1ec793f556640a01321 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 25 Oct 2023 10:13:23 +0530 Subject: [PATCH 22/29] fix m2m can handle --- .../validationhandler/impl/M2MScopeValidationHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java index 389a256c993..f59291075c3 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/M2MScopeValidationHandler.java @@ -35,7 +35,7 @@ public class M2MScopeValidationHandler implements ScopeValidationHandler { public boolean canHandle(ScopeValidationContext scopeValidationContext) { return OAuthConstants.GrantTypes.CLIENT_CREDENTIALS.equals(scopeValidationContext.getGrantType()) && - getPolicyID().equals("RBAC"); + scopeValidationContext.getPolicyId().equals("RBAC"); } @Override From 24717fcc5238069a053873f5aa87765923a74bfc Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 25 Oct 2023 13:55:07 +0530 Subject: [PATCH 23/29] handle switch grant --- .../identity/oauth2/util/AuthzUtil.java | 296 ++++++++++-------- .../impl/RoleBasedScopeValidationHandler.java | 3 +- 2 files changed, 166 insertions(+), 133 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java index 0d368b74834..9e427b5b417 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java @@ -26,15 +26,13 @@ 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; -import org.wso2.carbon.identity.application.common.model.IdPGroup; -import org.wso2.carbon.identity.application.common.model.IdentityProvider; import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementException; -import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.core.NotImplementedException; @@ -45,12 +43,11 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; -import java.util.stream.Collectors; +import static org.wso2.carbon.identity.role.v2.mgt.core.RoleConstants.APPLICATION; +import static org.wso2.carbon.identity.role.v2.mgt.core.RoleConstants.ORGANIZATION; import static org.wso2.carbon.user.core.UserCoreConstants.APPLICATION_DOMAIN; import static org.wso2.carbon.user.core.UserCoreConstants.INTERNAL_DOMAIN; @@ -68,31 +65,108 @@ public class AuthzUtil { * @return User roles. * @throws IdentityOAuth2Exception if an error occurs while retrieving user roles. */ - public static List getUserRoles(AuthenticatedUser authenticatedUser) + public static List getUserRoles(AuthenticatedUser authenticatedUser, String appId) throws IdentityOAuth2Exception { - List roleIds = new ArrayList<>(); - // Get role id list of the user. - List roleIdsOfUser = getRoleIdsOfUser(authenticatedUser); - if (!roleIdsOfUser.isEmpty()) { - roleIds.addAll(roleIdsOfUser); + if (authenticatedUser.isFederatedUser()) { + if (StringUtils.isNotBlank(authenticatedUser.getAccessingOrganization())) { + if (!authenticatedUser.getAccessingOrganization() + .equals(authenticatedUser.getUserResidentOrganization())) { + // Handle switching organization scenario. + String accessingTenantDomain = getAccessingTenantDomain(authenticatedUser); + String accessingUserId = getAccessingUserId(authenticatedUser); + return getRoles(accessingUserId, accessingTenantDomain); + } + } + // Handler federated user scenario. + return getFederatedRoles(authenticatedUser, appId); } - // Get groups of the user. - List groups = getUserGroups(authenticatedUser); + return getRoles(getUserId(authenticatedUser), authenticatedUser.getTenantDomain()); + } + + /** + * Get the role ids. + * + * @param userId User ID. + * @param tenantDomain Tenant domain. + * @return Role ids of user. + * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of user. + */ + private static List getRoles(String userId, String tenantDomain) throws IdentityOAuth2Exception { + + List roleIds = new ArrayList<>(getRoleIdsOfUser(userId, tenantDomain)); + List groups = getUserGroups(userId, tenantDomain); if (!groups.isEmpty()) { - List roleIdsOfGroups = getRoleIdsOfGroups(groups, authenticatedUser.getTenantDomain()); - if (!roleIdsOfGroups.isEmpty()) { - roleIds.addAll(roleIdsOfGroups); - } + roleIds.addAll(getRoleIdsOfGroups(groups, tenantDomain)); } - if (authenticatedUser.isFederatedUser()) { - List roleIdsOfIdpGroups = getRoleIdsOfIdpGroups(getUserIdpGroups(authenticatedUser), - authenticatedUser.getTenantDomain()); - if (!roleIdsOfIdpGroups.isEmpty()) { - roleIds.addAll(roleIdsOfIdpGroups); + return roleIds; + } + + /** + * Get the federated role ids. + * + * @param authenticatedUser Authenticated user. + * @return Federated role ids of user. + * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of user. + */ + private static List getFederatedRoles(AuthenticatedUser authenticatedUser, String appId) + throws IdentityOAuth2Exception { + + String tenantDomain = authenticatedUser.getTenantDomain(); + String roleNamesString = null; + Map claimMappingStringMap = authenticatedUser.getUserAttributes(); + if (claimMappingStringMap == null) { + return new ArrayList<>(); + } + for (Map.Entry entry : claimMappingStringMap.entrySet()) { + if (FrameworkConstants.LOCAL_ROLE_CLAIM_URI.equals(entry.getKey().getLocalClaim().getClaimUri())) { + roleNamesString = entry.getValue(); + break; } } - return roleIds; + List roleNames = null; + if (StringUtils.isNotBlank(roleNamesString)) { + roleNames = Arrays.asList(roleNamesString.split(FrameworkUtils.getMultiAttributeSeparator())); + } + if (roleNames == null || roleNames.isEmpty()) { + return new ArrayList<>(); + } + + String allowedAppAudience = getApplicationAllowedAudience(appId, tenantDomain); + if (ORGANIZATION.equalsIgnoreCase(allowedAppAudience)) { + + return getRoleIdsFromNames(roleNames, ORGANIZATION, getOrganizationId(tenantDomain), tenantDomain); + } + return getRoleIdsFromNames(roleNames, APPLICATION, appId, tenantDomain); + } + + /** + * Get accessing tenant domain of authenticated user. + * + * @param authenticatedUser Authenticated user. + * @return Accessing tenant domain. + * @throws IdentityOAuth2Exception if an error occurs while retrieving accessing tenant domain. + */ + private static String getAccessingTenantDomain(AuthenticatedUser authenticatedUser) throws IdentityOAuth2Exception { + try { + return OAuthComponentServiceHolder.getInstance().getOrganizationManager() + .resolveTenantDomain(authenticatedUser.getAccessingOrganization()); + } catch (OrganizationManagementException e) { + throw new IdentityOAuth2Exception("Error while retrieving accessing tenant domain", e); + } + } + + /** + * Get accessing user id of authenticated user. + * + * @param authenticatedUser Authenticated user. + * @return Accessing tenant domain. + * @throws IdentityOAuth2Exception if an error occurs while retrieving accessing user id. + */ + private static String getAccessingUserId(AuthenticatedUser authenticatedUser) throws IdentityOAuth2Exception { + + // TODO: resolve accessing user id. + return getUserId(authenticatedUser); } /** @@ -118,30 +192,13 @@ public static List getAssociatedScopesForRoles(List roles, Strin /** * Get the role ids of user. * - * @param authenticatedUser AuthenticatedUser. + * @param userId User ID. + * @param tenantDomain Tenant domain. * @return Role ids of user. * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of user. */ - private static List getRoleIdsOfUser(AuthenticatedUser authenticatedUser) throws IdentityOAuth2Exception { + private static List getRoleIdsOfUser(String userId, String tenantDomain) throws IdentityOAuth2Exception { - String tenantDomain = authenticatedUser.getTenantDomain(); - if (authenticatedUser.getAccessingOrganization() != null) { - try { - tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager() - .resolveTenantDomain(authenticatedUser.getUserResidentOrganization()); - } catch (OrganizationManagementException e) { - throw new RuntimeException(e); - } - } - String userId; - try { - userId = authenticatedUser.getUserId(); - } catch (UserIdNotFoundException e) { - throw new IdentityOAuth2Exception("Error while resolving user id of user" , e); - } - if (userId == null) { - throw new IdentityOAuth2Exception("user not found"); - } try { return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() .getRoleIdListOfUser(userId, tenantDomain); @@ -152,52 +209,92 @@ private static List getRoleIdsOfUser(AuthenticatedUser authenticatedUser } /** - * Get the role ids of user. + * Get user id of the user + * + * @param authenticatedUser Authenticated user. + * @return User id. + * @throws IdentityOAuth2Exception if an error occurs while retrieving user id of user. + */ + private static String getUserId(AuthenticatedUser authenticatedUser) throws IdentityOAuth2Exception { + + try { + return authenticatedUser.getUserId(); + } catch (UserIdNotFoundException e) { + throw new IdentityOAuth2Exception("Error while resolving user id of user" , e); + } + } + + /** + * Get organization id * - * @param userId User id. * @param tenantDomain Tenant domain. - * @return Role ids of user. - * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of user. + * @return Organization Id. + * @throws IdentityOAuth2Exception if an error occurs while retrieving org id. */ - private static List getRoleIdsOfUser2(String userId, String tenantDomain) throws IdentityOAuth2Exception { + private static String getOrganizationId(String tenantDomain) throws IdentityOAuth2Exception { try { - return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() - .getRoleIdListOfUser(userId, tenantDomain); - } catch (IdentityRoleManagementException e) { - throw new IdentityOAuth2Exception("Error while retrieving role id list of user : " + userId - + "tenant domain : " + tenantDomain, e); + return OAuthComponentServiceHolder.getInstance().getOrganizationManager() + .resolveOrganizationId(tenantDomain); + } catch (OrganizationManagementException e) { + throw new IdentityOAuth2Exception("Error while resolving org id of tenant : " + tenantDomain , e); } } /** - * Get the role ids of idp groups + * Get application allowed audience. * - * @param groups Groups. + * @param appId App id. * @param tenantDomain Tenant domain. + * @return Allowed audience of app. + * @throws IdentityOAuth2Exception if an error occurs while retrieving allowed audience of app. + */ + private static String getApplicationAllowedAudience(String appId, String tenantDomain) + throws IdentityOAuth2Exception { + + try { + return OAuth2ServiceComponentHolder.getApplicationMgtService() + .getAllowedAudienceForRoleAssociation(appId, tenantDomain); + } catch (IdentityApplicationManagementException e) { + throw new IdentityOAuth2Exception("Error while retrieving allowed audience of app : " + appId , e); + } + } + + /** + * Get the role ids from role names. + * + * @param roleNames Role names. + * @param tenantDomain Tenant domain. + * @param roleAudience Role audience. + * @param roleAudienceId Role audience id. * @return Role ids of idp groups. * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of idp groups. */ - private static List getRoleIdsOfIdpGroups(List groups, String tenantDomain) + private static List getRoleIdsFromNames(List roleNames, String roleAudience, String roleAudienceId, + String tenantDomain) throws IdentityOAuth2Exception { + List roleIds = new ArrayList<>(); try { - return OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() - .getRoleIdListOfIdpGroups(groups, tenantDomain); + for (String roleName: roleNames) { + roleIds.add(OAuth2ServiceComponentHolder.getInstance().getRoleManagementServiceV2() + .getRoleIdByName(roleName, roleAudience, roleAudienceId, tenantDomain)); + } } catch (IdentityRoleManagementException e) { - throw new IdentityOAuth2Exception("Error while retrieving role id list of groups : " - + StringUtils.join(groups, ",") + "tenant domain : " + tenantDomain, e); + throw new IdentityOAuth2Exception("Error while retrieving role ids of list of role anme : " + + StringUtils.join(roleNames, ",") + "tenant domain : " + tenantDomain, e); } + return roleIds; } /** * Get the groups of the authenticated user. * - * @param authenticatedUser Authenticated user. + * @param userId User id. + * @param tenantDomain Tenant domain. * @return - Groups of the user. */ - private static List getUserGroups(AuthenticatedUser authenticatedUser) - throws IdentityOAuth2Exception { + private static List getUserGroups(String userId, String tenantDomain) throws IdentityOAuth2Exception { if (LOG.isDebugEnabled()) { LOG.debug("Started group fetching for scope validation."); @@ -205,10 +302,10 @@ private static List getUserGroups(AuthenticatedUser authenticatedUser) List userGroups = new ArrayList<>(); RealmService realmService = UserCoreUtil.getRealmService(); try { - int tenantId = OAuth2Util.getTenantId(authenticatedUser.getTenantDomain()); + int tenantId = OAuth2Util.getTenantId(tenantDomain); UserStoreManager userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager(); List groups = - ((AbstractUserStoreManager) userStoreManager).getGroupListOfUser(authenticatedUser.getUserId(), + ((AbstractUserStoreManager) userStoreManager).getGroupListOfUser(userId, null, null); for (Group group : groups) { String groupName = group.getGroupName(); @@ -218,7 +315,7 @@ private static List getUserGroups(AuthenticatedUser authenticatedUser) userGroups.add(group.getGroupID()); } } - } catch (UserIdNotFoundException | IdentityOAuth2Exception e) { + } catch (IdentityOAuth2Exception e) { throw new IdentityOAuth2Exception(e.getMessage(), e); } catch (UserStoreException e) { if (isDoGetGroupListOfUserNotImplemented(e)) { @@ -232,71 +329,6 @@ private static List getUserGroups(AuthenticatedUser authenticatedUser) return userGroups; } - /** - * Get the groups of the authenticated user. - * - * @param authenticatedUser Authenticated user. - * @return - Groups of the user. - */ - private static List getUserIdpGroups(AuthenticatedUser authenticatedUser) - throws IdentityOAuth2Exception { - - LOG.debug("Started group fetching for scope validation."); - - String idpName = authenticatedUser.getFederatedIdPName(); - String tenantDomain = authenticatedUser.getTenantDomain(); - IdentityProvider federatedIdP = getIdentityProvider(idpName, tenantDomain); - List idpGroups = new ArrayList<>(Arrays.asList(federatedIdP.getIdPGroupConfig())); - // Convert idPGroups into a map for quick lookup - Map groupNameToIdMap = new HashMap<>(); - for (IdPGroup group : idpGroups) { - groupNameToIdMap.put(group.getIdpGroupName(), group.getIdpGroupId()); - } - if (federatedIdP != null) { - String idpGroupsClaimUri = Arrays.stream(federatedIdP.getClaimConfig().getClaimMappings()) - .filter(claimMapping -> claimMapping.getLocalClaim().getClaimUri() - .equals(FrameworkConstants.GROUPS_CLAIM)) - .map(claimMapping -> claimMapping.getRemoteClaim().getClaimUri()) - .findFirst() - .orElse(null); - // If there is no group claim mapping, no need to proceed. - if (idpGroupsClaimUri == null) { - return new ArrayList<>(); - } - Map userAttributes = authenticatedUser.getUserAttributes(); - for (Map.Entry entry : userAttributes.entrySet()) { - ClaimMapping claimMapping = entry.getKey(); - if (idpGroupsClaimUri.equals(claimMapping.getRemoteClaim().getClaimUri())) { - String idPGroupsClaim = entry.getValue(); - if (StringUtils.isNotBlank(idPGroupsClaim)) { - List groupNames = new ArrayList<>(Arrays.asList(idPGroupsClaim - .split(Pattern.quote(FrameworkUtils.getMultiAttributeSeparator())))); - return groupNames.stream().map(groupNameToIdMap::get).collect(Collectors.toList()); - } - } - } - } - return new ArrayList<>(); - } - - /** - * Get the Identity Provider object for the given identity provider name. - * - * @param idpName Identity provider name. - * @param tenantDomain Tenant domain. - * @return Identity Provider object. - * @throws IdentityOAuth2Exception Exception thrown when getting the identity provider. - */ - private static IdentityProvider getIdentityProvider(String idpName, String tenantDomain) - throws IdentityOAuth2Exception { - - try { - return OAuth2ServiceComponentHolder.getInstance().getIdpManager().getIdPByName(idpName, tenantDomain); - } catch (IdentityProviderManagementException e) { - throw new IdentityOAuth2Exception("Error while retrieving idp by idp name : " + idpName, e); - } - } - /** * Get the role ids of groups. * diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java index b0afda95f2b..c1194c26389 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java @@ -55,7 +55,8 @@ public List validateScopes(List requestedScopes, List ap throws ScopeValidationHandlerException { try { - List userRoles = AuthzUtil.getUserRoles(scopeValidationContext.getAuthenticatedUser()); + List userRoles = AuthzUtil.getUserRoles(scopeValidationContext.getAuthenticatedUser(), + scopeValidationContext.getAppId()); if (userRoles.isEmpty()) { return new ArrayList<>(); } From d51001498b672ef3f11b204247e036de838dfb8a Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 25 Oct 2023 14:14:56 +0530 Subject: [PATCH 24/29] fix xacml validator enagage --- .../org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java index 3fa652cd1b5..b255171003d 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/Oauth2ScopeUtils.java @@ -263,7 +263,8 @@ private static boolean iterateOAuth2ScopeValidators(OAuthAuthzReqMessageContext if (!AuthzUtil.isLegacyAuthzRuntime() && LEGACY_RBAC_SCOPE_VALIDATOR.equals(validator .getValidatorName())) { - return true; + appScopeValidators.remove(validator.getValidatorName()); + continue; } // Validate the scopes from the validator only if it's configured in the OAuth app. if (validator != null && appScopeValidators.contains(validator.getValidatorName())) { From 8c74de82a4a359a8526dece725f1ab384ac358f8 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 25 Oct 2023 14:28:12 +0530 Subject: [PATCH 25/29] fix method name --- .../java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java index 9e427b5b417..a24b2e0448f 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java @@ -79,7 +79,7 @@ public static List getUserRoles(AuthenticatedUser authenticatedUser, Str } } // Handler federated user scenario. - return getFederatedRoles(authenticatedUser, appId); + return getFederatedUserRoles(authenticatedUser, appId); } return getRoles(getUserId(authenticatedUser), authenticatedUser.getTenantDomain()); } @@ -109,7 +109,7 @@ private static List getRoles(String userId, String tenantDomain) throws * @return Federated role ids of user. * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of user. */ - private static List getFederatedRoles(AuthenticatedUser authenticatedUser, String appId) + private static List getFederatedUserRoles(AuthenticatedUser authenticatedUser, String appId) throws IdentityOAuth2Exception { String tenantDomain = authenticatedUser.getTenantDomain(); From ca667134a583eeba238d9c26c08075a8451eb419 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 25 Oct 2023 15:07:02 +0530 Subject: [PATCH 26/29] fix test failing --- components/org.wso2.carbon.identity.oauth/pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/pom.xml b/components/org.wso2.carbon.identity.oauth/pom.xml index f0d99ed8385..8bd57a8b376 100644 --- a/components/org.wso2.carbon.identity.oauth/pom.xml +++ b/components/org.wso2.carbon.identity.oauth/pom.xml @@ -332,12 +332,10 @@ org.wso2.carbon.identity.framework org.wso2.carbon.identity.api.resource.mgt - provided org.wso2.carbon.identity.framework org.wso2.carbon.identity.role.v2.mgt.core - provided From 2e4ee32dcd8e747e8329254e04ce1c4c96d37d8d Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 25 Oct 2023 17:44:58 +0530 Subject: [PATCH 27/29] remove SYSTEM scope from allowed scopes --- .../identity/oauth2/authz/AuthorizationHandlerManager.java | 2 +- .../wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java index 6e111c5fe2a..ec24550a8f6 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManager.java @@ -420,7 +420,7 @@ private void removeAuthorizedScopesFromRequestedScopes(OAuthAuthzReqMessageConte } List scopes = new ArrayList<>(); for (String scope : authzReqMsgCtx.getAuthorizationReqDTO().getScopes()) { - if (!authorizedScopes.contains(scope)) { + if (!authorizedScopes.contains(scope) && !scope.equalsIgnoreCase(SYSTEM_SCOPE)) { scopes.add(scope); } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java index 5c1abf694f4..2e1398b7782 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java @@ -1008,7 +1008,7 @@ private void removeAuthorizedScopes(OAuthTokenReqMessageContext tokReqMsgCtx, Li } List scopes = new ArrayList<>(); for (String scope : tokReqMsgCtx.getScope()) { - if (!authorizedScopes.contains(scope)) { + if (!authorizedScopes.contains(scope) && !scope.equalsIgnoreCase(SYSTEM_SCOPE)) { scopes.add(scope); } } From b4e8417b603a86c5666682395a16d3f6d9de2b3e Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Thu, 26 Oct 2023 12:18:01 +0530 Subject: [PATCH 28/29] fix console scopes issue --- .../identity/oauth2/util/AuthzUtil.java | 24 ++++++++++++++++--- .../DefaultOAuth2ScopeValidator.java | 20 ++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java index a24b2e0448f..9fdc6b7893d 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/AuthzUtil.java @@ -73,17 +73,35 @@ public static List getUserRoles(AuthenticatedUser authenticatedUser, Str if (!authenticatedUser.getAccessingOrganization() .equals(authenticatedUser.getUserResidentOrganization())) { // Handle switching organization scenario. - String accessingTenantDomain = getAccessingTenantDomain(authenticatedUser); - String accessingUserId = getAccessingUserId(authenticatedUser); - return getRoles(accessingUserId, accessingTenantDomain); + return getSwitchUserRoles(authenticatedUser); } } // Handler federated user scenario. return getFederatedUserRoles(authenticatedUser, appId); } + if (StringUtils.isNotBlank(authenticatedUser.getAccessingOrganization())) { + if (!authenticatedUser.getAccessingOrganization() + .equals(authenticatedUser.getUserResidentOrganization())) { + return getSwitchUserRoles(authenticatedUser); + } + } return getRoles(getUserId(authenticatedUser), authenticatedUser.getTenantDomain()); } + /** + * Get switching user roles. + * + * @param authenticatedUser Authenticated User. + * @return Switching user roles. + * @throws IdentityOAuth2Exception if an error occurs while retrieving role id list of switching user. + */ + private static List getSwitchUserRoles(AuthenticatedUser authenticatedUser) throws IdentityOAuth2Exception { + + String accessingTenantDomain = getAccessingTenantDomain(authenticatedUser); + String accessingUserId = getAccessingUserId(authenticatedUser); + return getRoles(accessingUserId, accessingTenantDomain); + } + /** * Get the role ids. * diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index 334bfbfa1c6..2a140065402 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -145,6 +145,7 @@ private List getAuthorizedScopes(List requestedScopes, Authentic requestedScopes = removeOIDCScopes(requestedScopes, requestedOIDCScopes); if (requestedScopes.contains(SYSTEM_SCOPE)) { requestedScopes.addAll(getInternalScopes(tenantDomain)); + requestedScopes.addAll(getConsoleScopes(tenantDomain)); } List authorizedScopesList = getAuthorizedScopes(appId, tenantDomain); List scopeValidationHandlers = @@ -234,6 +235,25 @@ private List getInternalScopes(String tenantDomain) throws IdentityOAuth } } + /** + * Get the Console scopes. + * + * @param tenantDomain Tenant domain. + * @return Console scopes. + * @throws IdentityOAuth2Exception if an error occurs while retrieving console scopes for tenant domain. + */ + private List getConsoleScopes(String tenantDomain) throws IdentityOAuth2Exception { + + try { + List scopes = OAuth2ServiceComponentHolder.getInstance() + .getApiResourceManager().getScopesByTenantDomain(tenantDomain, "name sw console:"); + return scopes.stream().map(Scope::getName).collect(Collectors.toCollection(ArrayList::new)); + } catch (APIResourceMgtException e) { + throw new IdentityOAuth2Exception("Error while retrieving console scopes for tenant domain : " + + tenantDomain, e); + } + } + /** * Get the registered scopes. * From 5f61cdeb3504624f856299dfa187711a77966243 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Thu, 26 Oct 2023 15:25:34 +0530 Subject: [PATCH 29/29] fix internal login scopes issue in client credentials --- .../oauth2/validators/DefaultOAuth2ScopeValidator.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java index 2a140065402..5a8649debb1 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java @@ -30,6 +30,7 @@ import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; import org.wso2.carbon.identity.oauth.IdentityOAuthAdminException; import org.wso2.carbon.identity.oauth.OAuthAdminServiceImpl; +import org.wso2.carbon.identity.oauth.common.OAuthConstants; import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext; @@ -50,6 +51,7 @@ import java.util.stream.Collectors; import static org.wso2.carbon.identity.oauth2.Oauth2ScopeConstants.SYSTEM_SCOPE; +import static org.wso2.carbon.identity.oauth2.util.OAuth2Util.INTERNAL_LOGIN_SCOPE; /** * Default oauth2 scope validator which validate application authorized scopes. @@ -112,6 +114,9 @@ public List validateScope(OAuthTokenReqMessageContext tokenReqMessageCon List authorizedScopes = getAuthorizedScopes(requestedScopes, tokenReqMessageContext .getAuthorizedUser(), appId, grantType, tenantDomain); removeRegisteredScopes(tokenReqMessageContext); + if (OAuthConstants.GrantTypes.CLIENT_CREDENTIALS.equals(grantType) && authorizedScopes.contains(SYSTEM_SCOPE)) { + authorizedScopes.remove(INTERNAL_LOGIN_SCOPE); + } return authorizedScopes; }