Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default OAuth2 Scope Validator implementation #2206

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0006d2a
add policy handlers
shashimalcse Oct 10, 2023
46756df
add new scope validtaor
shashimalcse Oct 12, 2023
fa30e13
add system scope handling
shashimalcse Oct 12, 2023
34473ae
filter role by apps
shashimalcse Oct 16, 2023
e04fcde
add user role resolving
shashimalcse Oct 19, 2023
0441a47
implement rbac
shashimalcse Oct 19, 2023
5832574
fix get user group and role ids list
shashimalcse Oct 19, 2023
a7aac52
fix getuser group
shashimalcse Oct 19, 2023
91e08be
fix null exception
shashimalcse Oct 20, 2023
ef401fe
introduce islegacyauthzruntime
shashimalcse Oct 21, 2023
01b9aa9
fix legacy app validator skip return
shashimalcse Oct 21, 2023
e1e097d
Merge branch 'master' into shashimalcse-patch-100
shashimalcse Oct 21, 2023
61125a7
fix formatting
shashimalcse Oct 21, 2023
392112b
fix xacml engagement
shashimalcse Oct 24, 2023
a0a1e66
Merge branch 'shashimalcse-patch-100' of https://github.com/shashimal…
shashimalcse Oct 24, 2023
c68a58d
fix user role resolver
shashimalcse Oct 24, 2023
7d590e9
remove registered scopes
shashimalcse Oct 24, 2023
e60d410
add authzutil class
shashimalcse Oct 24, 2023
1df3552
move legacy check to authzutil
shashimalcse Oct 24, 2023
3c1b5de
add licence headers
shashimalcse Oct 24, 2023
c697609
Merge branch 'master' into shashimalcse-patch-100
shashimalcse Oct 24, 2023
e9d52c8
fix for asub org user
shashimalcse Oct 24, 2023
22e54eb
fix conflict
shashimalcse Oct 24, 2023
213219c
fix kernel version
shashimalcse Oct 24, 2023
2f94647
fix compile issue wth fasterxml
shashimalcse Oct 25, 2023
02b537c
fix m2m can handle
shashimalcse Oct 25, 2023
24717fc
handle switch grant
shashimalcse Oct 25, 2023
d510014
fix xacml validator enagage
shashimalcse Oct 25, 2023
8c74de8
fix method name
shashimalcse Oct 25, 2023
ca66713
fix test failing
shashimalcse Oct 25, 2023
2e4ee32
remove SYSTEM scope from allowed scopes
shashimalcse Oct 25, 2023
b0c409a
Merge branch 'master' into shashimalcse-patch-100
shashimalcse Oct 25, 2023
b4e8417
fix console scopes issue
shashimalcse Oct 26, 2023
5f61cde
fix internal login scopes issue in client credentials
shashimalcse Oct 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions components/org.wso2.carbon.identity.oauth/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,14 @@
<artifactId>jaxp-ri</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.api.resource.mgt</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.role.v2.mgt.core</artifactId>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -423,6 +431,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}"
</Import-Package>
<Export-Package>
!org.wso2.carbon.identity.oauth.internal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
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.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;
Expand All @@ -57,6 +58,7 @@ public class OAuthComponentServiceHolder {
private List<TokenBindingMetaDataDTO> tokenBindingMetaDataDTOs = new ArrayList<>();
private OAuthAdminServiceImpl oAuthAdminService;
private List<ScopeValidator> scopeValidators = new ArrayList<>();
private List<ScopeValidationHandler> scopeValidationHandlers = new ArrayList<>();
private Map<Integer, OAuthApplicationMgtListener> oAuthApplicationMgtListeners = new TreeMap<>();
private RoleManagementService roleManagementService;
private OrganizationUserResidentResolverService organizationUserResidentResolverService;
Expand Down Expand Up @@ -105,6 +107,46 @@ public void setScopeValidators(List<ScopeValidator> scopeValidators) {
this.scopeValidators = scopeValidators;
}

/**
* Get the list of scope validation handler implementations available.
*
* @return ScopeValidationHandler returns a list ot scope validation policy handler.
*/
public List<ScopeValidationHandler> getScopeValidationHandlers() {

return scopeValidationHandlers;
}

/**
* Add scope validation handler implementation.
*
* @param scopeValidationHandler Scope validation handler implementation.
*/
public void addScopeValidationHandler(ScopeValidationHandler scopeValidationHandler) {

scopeValidationHandlers.add(scopeValidationHandler);
}

/**
* Remove scope validation policy implementation.
*
* @param scopeValidationHandler Scope validation policy implementation.
*/
public void removeScopeValidationHandler(ScopeValidationHandler scopeValidationHandler) {

scopeValidationHandlers.remove(scopeValidationHandler);
}

/**
* Set a list of scope validation handler implementations.
*
* @param scopeValidationHandlers List of Scope validation handler implementation.
*/
public void setScopeValidatorPolicyHandlers(List<ScopeValidationHandler> scopeValidationHandlers) {

this.scopeValidationHandlers = scopeValidationHandlers;
}

private OAuthComponentServiceHolder() {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
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;
import org.wso2.carbon.identity.oauth2.validators.RoleBasedInternalScopeValidator;
import org.wso2.carbon.utils.CarbonUtils;
Expand Down Expand Up @@ -276,15 +278,23 @@ private void validateRequestedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx,
List<String> 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);

// 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);
List<String> 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];
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 {
// Engage new scope validator
authorizedScopes = getAuthorizedScopes(authzReqMsgCtx);
removeAuthorizedScopesFromRequestedScopes(authzReqMsgCtx, authorizedScopes);
}
boolean isDropUnregisteredScopes = OAuthServerConfiguration.getInstance().isDropUnregisteredScopes();
if (isDropUnregisteredScopes) {
if (log.isDebugEnabled()) {
Expand All @@ -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 (AuthzUtil.isLegacyAuthzRuntime()) {
// 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 {
Expand Down Expand Up @@ -359,6 +373,19 @@ private String[] getAuthorizedInternalScopes(OAuthAuthzReqMessageContext authzRe
return authorizedInternalScopes;
}

/**
* get authorized scopes.
*
* @param authzReqMsgCtx authzReqMsgCtx
* @return - authorizedInternalScopes scopes list
*/
private List<String> getAuthorizedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx)
throws IdentityOAuth2Exception {

DefaultOAuth2ScopeValidator scopeValidator = new DefaultOAuth2ScopeValidator();
return scopeValidator.validateScope(authzReqMsgCtx);
}

/**
* Eemove internal scopes from requested scopes.
*
Expand All @@ -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<String> authorizedScopes) {

if (authzReqMsgCtx.getAuthorizationReqDTO().getScopes() == null) {
return;
}
List<String> scopes = new ArrayList<>();
for (String scope : authzReqMsgCtx.getAuthorizationReqDTO().getScopes()) {
if (!authorizedScopes.contains(scope) && !scope.equalsIgnoreCase(SYSTEM_SCOPE)) {
scopes.add(scope);
}
}
authzReqMsgCtx.getAuthorizationReqDTO().setScopes(scopes.toArray(new String[0]));
}

/**
* Remove the system level allowed scopes from requested scopes.
*
Expand Down Expand Up @@ -419,6 +467,14 @@ private void addAuthorizedInternalScopes(OAuthAuthzReqMessageContext authzReqMsg
authzReqMsgCtx.setApprovedScope(scopesToReturn);
}

private void addAuthorizedScopes(OAuthAuthzReqMessageContext authzReqMsgCtx, List<String> authorizedScopes) {

String[] scopes = authzReqMsgCtx.getApprovedScope();
String[] scopesToReturn = (String[]) ArrayUtils.addAll(scopes, authorizedScopes.toArray());
authzReqMsgCtx.setApprovedScope(scopesToReturn);
}


private void addRequestedOIDCScopes(OAuthAuthzReqMessageContext authzReqMsgCtx,
String[] requestedOIDCScopes) {
Set<String> scopesToReturn = new HashSet<>(Arrays.asList(authzReqMsgCtx.getApprovedScope()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -80,6 +82,10 @@
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
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;
Expand All @@ -88,6 +94,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;
Expand Down Expand Up @@ -332,6 +339,9 @@ 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(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

Expand Down Expand Up @@ -607,6 +617,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,
Expand Down Expand Up @@ -1222,4 +1255,85 @@ 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) {

if (log.isDebugEnabled()) {
log.debug("Adding Authorized API Management Service: " + authorizedAPIManagementService.getClass()
.getName());
}
OAuth2ServiceComponentHolder.getInstance()
shashimalcse marked this conversation as resolved.
Show resolved Hide resolved
.setAuthorizedAPIManagementService(authorizedAPIManagementService);
}

protected void unsetAuthorizedAPIManagementService(AuthorizedAPIManagementService authorizedAPIManagementService) {

if (log.isDebugEnabled()) {
log.debug("Removing Authorized API Management Service: " + authorizedAPIManagementService.getClass()
.getName());
}
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) {

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);
}

/**
* 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) {

if (log.isDebugEnabled()) {
log.debug("Adding Role Management Service V2: " + roleManagementService.getClass().getName());
}
OAuth2ServiceComponentHolder.getInstance().setRoleManagementServiceV2(roleManagementService);
}

/**
* Unset role management service V2 implementation.
*
* @param roleManagementService RoleManagementServiceV2
*/
protected void unsetRoleManagementServiceV2(RoleManagementService roleManagementService) {

if (log.isDebugEnabled()) {
log.debug("Removing Role Management Service V2: " + roleManagementService.getClass().getName());
}
OAuth2ServiceComponentHolder.getInstance().setRoleManagementServiceV2(null);
}

}
Loading
Loading