Skip to content

Commit

Permalink
Remove sub org app check from authz and token handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
ShanChathusanda93 committed Dec 1, 2024
1 parent e308fa5 commit fddecc4
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants;
import org.wso2.carbon.identity.application.common.model.ProvisioningServiceProviderType;
import org.wso2.carbon.identity.application.common.model.ServiceProvider;
import org.wso2.carbon.identity.application.common.model.ServiceProviderProperty;
import org.wso2.carbon.identity.application.common.model.ThreadLocalProvisioningServiceProvider;
import org.wso2.carbon.identity.application.common.model.User;
import org.wso2.carbon.identity.application.common.util.IdentityApplicationManagementUtil;
Expand All @@ -41,6 +40,7 @@
import org.wso2.carbon.identity.auth.service.AuthenticationResult;
import org.wso2.carbon.identity.auth.service.AuthenticationStatus;
import org.wso2.carbon.identity.auth.service.handler.AuthenticationHandler;
import org.wso2.carbon.identity.auth.service.internal.AuthenticationServiceHolder;
import org.wso2.carbon.identity.auth.service.util.AuthConfigurationUtil;
import org.wso2.carbon.identity.auth.service.util.Constants;
import org.wso2.carbon.identity.core.bean.context.MessageContext;
Expand All @@ -56,6 +56,7 @@
import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinding;
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
import org.wso2.carbon.identity.oauth2.validators.RefreshTokenValidator;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;

import java.text.ParseException;
import java.util.Arrays;
Expand Down Expand Up @@ -175,20 +176,18 @@ protected AuthenticationResult doAuthenticate(MessageContext messageContext) {
ServiceProvider serviceProvider = null;
String serviceProviderName = null;
String serviceProviderUUID = null;
boolean isSubOrgApp = false;
String accessingTenantDomain = null;
try {
// Getting the accessing tenant domain from the authenticated user through the introspection
// response where the token is introspected.
if (authorizedUser != null) {
ServiceProviderProperty[] serviceProviderProperties = OAuth2Util.getServiceProvider(
oAuth2IntrospectionResponseDTO.getClientId(), authorizedUser.getTenantDomain()).
getSpProperties();
if (serviceProviderProperties != null && Arrays.stream(serviceProviderProperties)
.anyMatch(property -> "isSubOrgApp".equals(property.getName())
&& Boolean.parseBoolean(property.getValue()))) {
isSubOrgApp = true;
authenticationContext.addParameter("isSubOrgApp", true);
serviceProvider = OAuth2Util.getServiceProvider(oAuth2IntrospectionResponseDTO.getClientId(),
authorizedUser.getTenantDomain());
}
accessingTenantDomain = authorizedUser.getTenantDomain();
serviceProvider = OAuth2Util.getServiceProvider(
oAuth2IntrospectionResponseDTO.getClientId(), accessingTenantDomain);
boolean isSharedApp = Arrays.stream(serviceProvider.getSpProperties()).anyMatch(
property -> "isAppShared".equals(property.getName()) &&
Boolean.parseBoolean(property.getValue()));
authenticationContext.addParameter("isAppShared", isSharedApp);
} else {
serviceProvider = OAuth2Util.getServiceProvider(oAuth2IntrospectionResponseDTO.getClientId());
}
Expand All @@ -210,11 +209,13 @@ protected AuthenticationResult doAuthenticate(MessageContext messageContext) {

String serviceProviderTenantDomain = null;
try {
if (serviceProvider != null && isSubOrgApp) {
serviceProviderTenantDomain = serviceProvider.getTenantDomain();
if (StringUtils.isNotEmpty(accessingTenantDomain)) {
serviceProviderTenantDomain =
OAuth2Util.getTenantDomainOfOauthApp(oAuth2IntrospectionResponseDTO.getClientId(),
accessingTenantDomain);
} else {
serviceProviderTenantDomain = OAuth2Util.getTenantDomainOfOauthApp(
oAuth2IntrospectionResponseDTO.getClientId());
serviceProviderTenantDomain =
OAuth2Util.getTenantDomainOfOauthApp(oAuth2IntrospectionResponseDTO.getClientId());
}
} catch (InvalidOAuthClientException | IdentityOAuth2Exception e) {
if (log.isDebugEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.wso2.carbon.identity.organization.management.authz.service.OrganizationManagementAuthorizationContext;
import org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
import org.wso2.carbon.identity.organization.management.service.util.OrganizationManagementUtil;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;

import java.io.IOException;
Expand Down Expand Up @@ -85,25 +86,37 @@ public void invoke(Request request, Response response) throws IOException, Servl
}

String requestURI = request.getRequestURI();
if (!isRequestValidForTenant(authenticationContext, authorizationContext, request)) {
String spTenantDomain = null;
String isAppSharedStr = null;
if (authenticationContext.getParameter("serviceProviderTenantDomain") != null) {
spTenantDomain = authenticationContext.getParameter("serviceProviderTenantDomain").toString();
}
if (authenticationContext.getParameter("isAppShared") != null) {
isAppSharedStr = authenticationContext.getParameter("isAppShared").toString();
}
// If the application is not a shared application and the tenant is an organization, skip the
// request validation for the tenant.
if (!isSubOrganizationApp(spTenantDomain, isAppSharedStr)) {
if (!isRequestValidForTenant(authenticationContext, authorizationContext, request)) {
/*
Forbidden the /o/<org-id> path requests if the org level authz failed and
resource is not cross tenant allowed or authenticated user doesn't belong to the accessed resource's org.
*/
if (requestURI.startsWith(ORGANIZATION_PATH_PARAM)) {
if (requestURI.startsWith(ORGANIZATION_PATH_PARAM)) {
APIErrorResponseHandler.handleErrorResponse(authenticationContext, response,
HttpServletResponse.SC_FORBIDDEN, null);
return;
}
if (log.isDebugEnabled()) {
log.debug("Authorization to " + request.getRequestURI()
+ " is denied because the authenticated user belongs to different tenant domain: "
+ authenticationContext.getUser().getTenantDomain()
+ " and cross-domain access for the tenant is disabled.");
}
APIErrorResponseHandler.handleErrorResponse(authenticationContext, response,
HttpServletResponse.SC_FORBIDDEN, null);
HttpServletResponse.SC_UNAUTHORIZED, null);
return;
}
if (log.isDebugEnabled()) {
log.debug("Authorization to " + request.getRequestURI()
+ " is denied because the authenticated user belongs to different tenant domain: "
+ authenticationContext.getUser().getTenantDomain()
+ " and cross-domain access for the tenant is disabled.");
}
APIErrorResponseHandler.handleErrorResponse(authenticationContext, response,
HttpServletResponse.SC_UNAUTHORIZED, null);
return;
}

if (!isUserEmpty(authenticationContext)) {
Expand Down Expand Up @@ -235,11 +248,7 @@ private AuthorizationResult authorizeInOrganizationLevel(Request request, Respon
private boolean isRequestValidForTenant(AuthenticationContext authenticationContext,
AuthorizationContext authorizationContext, Request request) {

boolean isSubOrgApp = false;
if (authenticationContext.getParameter("isSubOrgApp") != null) {
isSubOrgApp = Boolean.parseBoolean(authenticationContext.getParameter("isSubOrgApp").toString());
}
return (Utils.isUserBelongsToRequestedTenant(authenticationContext, request) || isSubOrgApp ||
return (Utils.isUserBelongsToRequestedTenant(authenticationContext, request) ||
(authorizationContext.isCrossTenantAllowed()) &&
Utils.isTenantBelongsToAllowedCrossTenant(authenticationContext, authorizationContext));
}
Expand Down Expand Up @@ -303,4 +312,20 @@ private void startOrganizationBoundTenantFlow(String authorizedOrganization) {
throw new AuthRuntimeException("Error while resolving tenant domain by organization.", e);
}
}

private boolean isSubOrganizationApp (String spTenantDomain, String isAppShared) {

try {
if (StringUtils.isNotEmpty(spTenantDomain) && StringUtils.isNotEmpty(isAppShared)) {
if (OrganizationManagementUtil.isOrganization(spTenantDomain) && !Boolean.parseBoolean(isAppShared)) {
return true;
}
} else {
return false;
}
} catch (OrganizationManagementException e) {
throw new AuthRuntimeException("Error while checking the tenant is an organization.", e);
}
return false;
}
}

0 comments on commit fddecc4

Please sign in to comment.