Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2024, WSO2 LLC. (http://www.wso2.com).
* Copyright (c) 2014-2026, 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
Expand Down Expand Up @@ -123,6 +123,10 @@ private ApplicationConstants() {
public static final String APPLICATION_NAME_CONFIG_ELEMENT = "ApplicationName";
public static final String PORTAL_NAMES_CONFIG_ELEMENT = "SystemPortals.PortalName";

// Application API Authorization Management Service Configurations.
public static final String APPLICATION_API_AUTHORIZATION_BLOCKED_API_RESOURCES =
"APIResourceManagement.ApplicationAPIAuthorization.BlockedAPIResources.Identifier";

// Application Management Service Configurations.
public static final String ENABLE_APPLICATION_ROLE_VALIDATION_PROPERTY = "ApplicationMgt.EnableRoleValidation";
public static final String TRUSTED_APP_CONSENT_REQUIRED_PROPERTY = "ApplicationMgt.TrustedAppConsentRequired";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@

import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.Error.INVALID_REQUEST;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.Error.UNEXPECTED_SERVER_ERROR;
import static org.wso2.carbon.identity.application.mgt.ApplicationConstants.APPLICATION_API_AUTHORIZATION_BLOCKED_API_RESOURCES;
import static org.wso2.carbon.identity.application.mgt.ApplicationConstants.AUTHORIZE_ALL_SCOPES;
import static org.wso2.carbon.identity.application.mgt.ApplicationConstants.AUTHORIZE_INTERNAL_SCOPES;
import static org.wso2.carbon.identity.application.mgt.ApplicationConstants.ENABLE_CROSS_TENANT_AUTHORIZED_API_VALIDATION_PROPERTY;
Expand Down Expand Up @@ -83,6 +84,7 @@ public void addAuthorizedAPI(String applicationId, AuthorizedAPI authorizedAPI,

ApplicationManagementService applicationManagementService = ApplicationManagementServiceImpl.getInstance();
validateTenantDomain(applicationId, tenantDomain, applicationManagementService);
validateAPIResourceNotBlocked(authorizedAPI.getAPIId(), tenantDomain);

ApplicationAuthorizedAPIManagementEventPublisherProxy publisherProxy =
ApplicationAuthorizedAPIManagementEventPublisherProxy.getInstance();
Expand Down Expand Up @@ -323,6 +325,29 @@ private IdentityApplicationManagementClientException buildClientException(
return new IdentityApplicationManagementClientException(errorMessage.getCode(), message);
}

private void validateAPIResourceNotBlocked(String apiId, String tenantDomain)
throws IdentityApplicationManagementException {

if (StringUtils.isBlank(apiId)) {
return;
}
try {
APIResource apiResource = ApplicationManagementServiceComponentHolder.getInstance()
.getAPIResourceManager().getAPIResourceById(apiId, tenantDomain);
if (apiResource == null || StringUtils.isBlank(apiResource.getIdentifier())) {
return;
}
List<String> blockedIdentifiers = IdentityUtil.getPropertyAsList(
APPLICATION_API_AUTHORIZATION_BLOCKED_API_RESOURCES);
if (blockedIdentifiers.contains(apiResource.getIdentifier())) {
throw buildClientException(INVALID_REQUEST, "API resource '" + apiResource.getIdentifier()
+ "' is blocked from being authorized to applications.");
}
} catch (APIResourceMgtException e) {
Comment thread
ashanthamara marked this conversation as resolved.
throw buildServerException("Error while retrieving API resource for apiId: " + apiId, e);
}
}

private IdentityApplicationManagementServerException buildServerException(String message, Throwable ex) {

return new IdentityApplicationManagementServerException(UNEXPECTED_SERVER_ERROR.getCode(), message, ex);
Expand Down Expand Up @@ -370,6 +395,7 @@ public void patchAuthorizedAPI(String appId, String apiId, List<String> addedSco

ApplicationManagementService applicationManagementService = ApplicationManagementServiceImpl.getInstance();
validateTenantDomain(appId, tenantDomain, applicationManagementService);
validateAPIResourceNotBlocked(apiId, tenantDomain);
ApplicationAuthorizedAPIManagementEventPublisherProxy publisherProxy =
ApplicationAuthorizedAPIManagementEventPublisherProxy.getInstance();
publisherProxy.publishPreUpdateAuthorizedAPIForApplication(appId, apiId, addedScopes, removedScopes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.wso2.carbon.identity.api.resource.mgt.util.AuthorizationDetailsTypesUtil;
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementClientException;
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
import org.wso2.carbon.identity.application.common.model.APIResource;
import org.wso2.carbon.identity.application.common.model.AuthorizationDetailsType;
import org.wso2.carbon.identity.application.common.model.AuthorizedAPI;
import org.wso2.carbon.identity.application.common.model.AuthorizedScopes;
Expand All @@ -38,6 +39,7 @@
import org.wso2.carbon.identity.application.mgt.util.ScopeAuthorizationInfo;
import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
import org.wso2.carbon.identity.organization.management.service.util.OrganizationManagementUtil;
Expand Down Expand Up @@ -412,6 +414,8 @@
throws SQLException, IdentityApplicationManagementException {

List<ScopeAuthorizationInfo> systemApiScopes = resolveSystemApiScopesByName(dbConnection, scopes);
Comment thread
ashanthamara marked this conversation as resolved.
// Silently drop other system APIs being auto authorized based on the server-wide blocked list.
systemApiScopes = filterBlockedAPIScopes(systemApiScopes, apiId, tenantId);
boolean hasSharedScopes = systemApiScopes.stream().anyMatch(scopeInfo -> !scopeInfo.getApiId().equals(apiId));

if (hasSharedScopes) {
Expand Down Expand Up @@ -595,6 +599,56 @@
}
}

private List<ScopeAuthorizationInfo> filterBlockedAPIScopes(List<ScopeAuthorizationInfo> systemApiScopes,
String primaryApiId, int tenantId)
throws IdentityApplicationManagementException {

if (CollectionUtils.isEmpty(systemApiScopes)) {
return systemApiScopes;
}
List<String> blockedIdentifiers = IdentityUtil.getPropertyAsList(
ApplicationConstants.APPLICATION_API_AUTHORIZATION_BLOCKED_API_RESOURCES);
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("Blocked API identifiers from the server config: %s", blockedIdentifiers));
}
if (blockedIdentifiers.isEmpty()) {
return systemApiScopes;
}
// Identify other API resources that share scopes with the primary API resource.
Set<String> nonPrimaryApiIds = systemApiScopes.stream()
.map(ScopeAuthorizationInfo::getApiId)
.filter(id -> !id.equals(primaryApiId))
.collect(Collectors.toSet());
if (nonPrimaryApiIds.isEmpty()) {
return systemApiScopes;
}
String tenantDomain = IdentityTenantUtil.getTenantDomain(tenantId);
Set<String> blockedApiIds = new HashSet<>();
for (String apiId : nonPrimaryApiIds) {
try {
APIResource apiResource = ApplicationManagementServiceComponentHolder.getInstance()
.getAPIResourceManager().getAPIResourceById(apiId, tenantDomain);
if (apiResource != null && !StringUtils.isBlank(apiResource.getIdentifier())
&& blockedIdentifiers.contains(apiResource.getIdentifier())) {
blockedApiIds.add(apiId);
}
} catch (APIResourceMgtException e) {
Comment thread
ashanthamara marked this conversation as resolved.
throw new IdentityApplicationManagementException("Error while retrieving API resource for apiId: "
+ apiId, e);
}
}
if (blockedApiIds.isEmpty()) {
return systemApiScopes;
}
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("Skipping implicit cross-API authorization for %d blocked API Id(s): %s",
blockedApiIds.size(), blockedApiIds));
}
return systemApiScopes.stream()
.filter(scopeInfo -> !blockedApiIds.contains(scopeInfo.getApiId()))
.collect(Collectors.toList());

Check warning on line 649 in components/application-mgt/org.wso2.carbon.identity.application.mgt/src/main/java/org/wso2/carbon/identity/application/mgt/dao/impl/AuthorizedAPIDAOImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this usage of 'Stream.collect(Collectors.toList())' with 'Stream.toList()' and ensure that the list is unmodified.

See more on https://sonarcloud.io/project/issues?id=wso2_carbon-identity-framework&issues=AZ4eV_hD1b3tRzWArDHr&open=AZ4eV_hD1b3tRzWArDHr&pullRequest=8095
}

/**
* Get already authorized APIs from a set of API IDs in a single query.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public void setUp() throws Exception {
identityEventService = mock(IdentityEventService.class);
doNothing().when(identityEventService).handleEvent(any());
ApplicationManagementServiceComponentHolder.getInstance().setIdentityEventService(identityEventService);
ApplicationManagementServiceComponentHolder.getInstance().setAPIResourceManager(apiResourceManager);
APIResourceManagementServiceComponentHolder.getInstance().setRichAuthorizationRequestsEnabled(true);
APIResourceManagementServiceComponentHolder.getInstance().setIdentityEventService(identityEventService);
CarbonConstants.ENABLE_LEGACY_AUTHZ_RUNTIME = false;
Expand Down Expand Up @@ -148,7 +149,6 @@ public Object[][] createAuthorizedAPIDataProvider() throws Exception {
public void testCreateAuthorizedAPI(AuthorizedAPI authorizedAPI, int expectedAPIs)
throws Exception {

ApplicationManagementServiceComponentHolder.getInstance().setAPIResourceManager(apiResourceManager);
authorizedAPIManagementService.addAuthorizedAPI(authorizedAPI.getAppId(), authorizedAPI, tenantDomain);
List<AuthorizedAPI> authorizedAPIS = authorizedAPIManagementService.getAuthorizedAPIs(authorizedAPI.getAppId(),
tenantDomain);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023-2024, WSO2 LLC. (http://www.wso2.com).
* Copyright (c) 2023-2026, 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
Expand Down Expand Up @@ -85,6 +85,8 @@ private RoleConstants() {

// Role management service configurations.
public static final String ALLOW_SYSTEM_PREFIX_FOR_ROLES = "RoleMgt.AllowSystemPrefixForRoles";
public static final String ROLE_PERMISSION_ASSIGNMENT_BLOCKED_API_RESOURCES =
"APIResourceManagement.RolePermissionAssignment.BlockedAPIResources.Identifier";

// Role properties
public static final String IS_SHARED_ROLE_PROP_NAME = "isSharedRole";
Expand Down Expand Up @@ -114,6 +116,7 @@ public static class RoleTableColumns {
public static final String ROLE_ID = "ROLE_ID";
public static final String UM_ROLE_ID = "UM_ROLE_ID";
public static final String SCOPE_NAME = "SCOPE_NAME";
public static final String SCOPE_ID = "SCOPE_ID";
public static final String APP_ID = "APP_ID";
public static final String UM_SHARED_ROLE_ID = "UM_SHARED_ROLE_ID";
public static final String UM_SHARED_ROLE_TENANT_ID = "UM_SHARED_ROLE_TENANT_ID";
Expand Down
Loading
Loading