Skip to content

Commit

Permalink
Allow sub organization applications to issue tokens to access the res…
Browse files Browse the repository at this point in the history
…ources in sub organizations
  • Loading branch information
ShanChathusanda93 committed Nov 1, 2024
1 parent 1cef061 commit ecb8ca8
Show file tree
Hide file tree
Showing 14 changed files with 203 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.commons.logging.LogFactory;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.owasp.encoder.Encode;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.AbstractAdmin;
import org.wso2.carbon.identity.base.IdentityException;
import org.wso2.carbon.identity.central.log.mgt.utils.LogConstants;
Expand Down Expand Up @@ -63,6 +64,7 @@
import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinder;
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
import org.wso2.carbon.identity.openidconnect.model.Constants;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
import org.wso2.carbon.user.api.Claim;
import org.wso2.carbon.user.core.UserStoreManager;
import org.wso2.carbon.utils.DiagnosticLog;
Expand Down Expand Up @@ -981,7 +983,19 @@ public Claim[] getUserClaims(String accessTokenIdentifier) {
public String getOauthApplicationState(String consumerKey) {

try {
OAuthAppDO appDO = OAuth2Util.getAppInformationByClientId(consumerKey);
String tenantDomain = IdentityTenantUtil.getTenantDomain(IdentityTenantUtil.getLoginTenantId());
String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getApplicationResidentOrganizationId();
if (StringUtils.isNotEmpty(appOrgId)) {
try {
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
.resolveTenantDomain(appOrgId);
} catch (OrganizationManagementException e) {
throw new IdentityOAuth2Exception("Error while resolving tenant domain for the organization ID: " +
appOrgId, e);
}
}
OAuthAppDO appDO = OAuth2Util.getAppInformationByClientId(consumerKey, tenantDomain);
return appDO.getState();
} catch (IdentityOAuth2Exception e) {
log.error("Error while finding application state for application with client_id: " + consumerKey, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.oltu.oauth2.common.OAuth;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.oauth.IdentityOAuthAdminException;
import org.wso2.carbon.identity.oauth.common.OAuth2ErrorCodes;
import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthClientException;
import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder;
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
import org.wso2.carbon.identity.oauth2.bean.OAuthClientAuthnContext;
import org.wso2.carbon.identity.oauth2.model.ClientAuthenticationMethodModel;
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;

import java.util.ArrayList;
import java.util.Base64;
Expand Down Expand Up @@ -89,8 +93,20 @@ public boolean authenticateClient(HttpServletRequest request, Map<String, List>
log.debug("Authenticating client : " + oAuthClientAuthnContext.getClientId() + " with client " +
"secret.");
}
String tenantDomain = IdentityTenantUtil.resolveTenantDomain();
String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getApplicationResidentOrganizationId();
if (StringUtils.isNotEmpty(appOrgId)) {
try {
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
.resolveTenantDomain(appOrgId);
} catch (OrganizationManagementException e) {
throw new InvalidOAuthClientException("Error while resolving tenant domain for the organization " +
"ID: " + appOrgId, e);
}
}
return OAuth2Util.authenticateClient(oAuthClientAuthnContext.getClientId(),
(String) oAuthClientAuthnContext.getParameter(OAuth.OAUTH_CLIENT_SECRET));
(String) oAuthClientAuthnContext.getParameter(OAuth.OAUTH_CLIENT_SECRET), tenantDomain);
} catch (IdentityOAuthAdminException e) {
throw new OAuthClientAuthnException("Error while authenticating client",
OAuth2ErrorCodes.INVALID_CLIENT, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.oauth.common.OAuth2ErrorCodes;
import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthClientException;
import org.wso2.carbon.identity.oauth.dao.OAuthAppDO;
import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder;
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
import org.wso2.carbon.identity.oauth2.bean.OAuthClientAuthnContext;
import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder;
import org.wso2.carbon.identity.oauth2.model.ClientAuthenticationMethodModel;
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;

import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -321,6 +324,17 @@ private List<OAuthClientAuthenticator> getConfiguredClientAuthMethods(String cli
throws OAuthClientAuthnException, InvalidOAuthClientException {

String tenantDomain = IdentityTenantUtil.resolveTenantDomain();
String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getApplicationResidentOrganizationId();
if (StringUtils.isNotEmpty(appOrgId)) {
try {
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
.resolveTenantDomain(appOrgId);
} catch (OrganizationManagementException e) {
throw new InvalidOAuthClientException("Error while resolving tenant domain for the organization ID: " +
appOrgId, e);
}
}
List<String> configuredClientAuthMethods = new ArrayList<>();
try {
OAuthAppDO oAuthAppDO = OAuth2Util.getAppInformationByClientId(clientId, tenantDomain);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.database.utils.jdbc.JdbcTemplate;
import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException;
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
Expand Down Expand Up @@ -251,6 +252,18 @@ private void insertAccessToken(String accessToken, String consumerKey, AccessTok
insertTokenPrepStmt.setString(19, authorizedOrganization);

int appTenantId = IdentityTenantUtil.getLoginTenantId();
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getApplicationResidentOrganizationId();
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
try {
String tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
.resolveTenantDomain(applicationResidentOrgId);
appTenantId = OAuth2Util.getTenantId(tenantDomain);
} catch (OrganizationManagementException e) {
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
+ applicationResidentOrgId, e);
}
}
if (OAuth2ServiceComponentHolder.isIDPIdColumnEnabled()) {
if (OAuth2ServiceComponentHolder.isConsentedTokenColumnEnabled()) {
insertTokenPrepStmt.setString(20, Boolean.toString(accessTokenDO.isConsentedToken()));
Expand All @@ -276,8 +289,6 @@ private void insertAccessToken(String accessToken, String consumerKey, AccessTok
insertTokenPrepStmt.setInt(21, appTenantId);
}
}
insertTokenPrepStmt.executeUpdate();

String accessTokenId = accessTokenDO.getTokenId();
addScopePrepStmt = connection.prepareStatement(sqlAddScopes);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
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.ServiceProvider;
Expand Down Expand Up @@ -163,7 +164,20 @@ public RefreshTokenValidationDataDO validateRefreshToken(String consumerKey, Str
prepStmt = connection.prepareStatement(sql);

prepStmt.setString(1, getPersistenceProcessor().getProcessedClientId(consumerKey));
prepStmt.setInt(2, IdentityTenantUtil.getLoginTenantId());
int tenantId = IdentityTenantUtil.getLoginTenantId();
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getApplicationResidentOrganizationId();
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
try {
String tenantDomain = OAuth2ServiceComponentHolder.getInstance().getOrganizationManager()
.resolveTenantDomain(applicationResidentOrgId);
tenantId = IdentityTenantUtil.getTenantId(tenantDomain);
} catch (OrganizationManagementException e) {
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
+ applicationResidentOrgId, e);
}
}
prepStmt.setInt(2, tenantId);
if (refreshToken != null) {
prepStmt.setString(3, getHashingPersistenceProcessor().getProcessedRefreshToken(refreshToken));
}
Expand All @@ -183,7 +197,7 @@ public RefreshTokenValidationDataDO validateRefreshToken(String consumerKey, Str
validationDataDO.setAccessToken(resultSet.getString(1));
}
String userName = resultSet.getString(2);
int tenantId = resultSet.getInt(3);
tenantId = resultSet.getInt(3);
String userDomain = resultSet.getString(4);
String tenantDomain = OAuth2Util.getTenantDomain(tenantId);
validationDataDO.setRefreshToken(refreshToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.oltu.oauth2.common.error.OAuthError;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.owasp.encoder.Encode;
import org.wso2.carbon.context.PrivilegedCarbonContext;
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.common.IdentityApplicationManagementException;
Expand Down Expand Up @@ -167,7 +168,7 @@ public static AccessTokenIssuer getInstance() throws IdentityOAuth2Exception {
public OAuth2AccessTokenRespDTO issue(OAuth2AccessTokenReqDTO tokenReqDTO)
throws IdentityException {

String grantType = tokenReqDTO.getGrantType();
String grantType = tokenReqDTO.getGrantType(); // This is the place that we need to check the authorized user.
OAuth2AccessTokenRespDTO tokenRespDTO = null;

AuthorizationGrantHandler authzGrantHandler = authzGrantHandlers.get(grantType);
Expand Down Expand Up @@ -308,6 +309,11 @@ public OAuth2AccessTokenRespDTO issue(OAuth2AccessTokenReqDTO tokenReqDTO)
if (!isOfTypeApplicationUser) {
tokReqMsgCtx.setAuthorizedUser(oAuthAppDO.getAppOwner());
tokReqMsgCtx.addProperty(OAuthConstants.UserType.USER_TYPE, OAuthConstants.UserType.APPLICATION);
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getApplicationResidentOrganizationId();
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
tokReqMsgCtx.getAuthorizedUser().setAccessingOrganization(applicationResidentOrgId);
}
} else {
tokReqMsgCtx.addProperty(OAuthConstants.UserType.USER_TYPE, OAuthConstants.UserType.APPLICATION_USER);
}
Expand Down Expand Up @@ -1355,7 +1361,19 @@ private void setResponseHeaders(OAuthTokenReqMessageContext tokReqMsgCtx,
private OAuthAppDO getOAuthApplication(String consumerKey) throws InvalidOAuthClientException,
IdentityOAuth2Exception {

OAuthAppDO authAppDO = OAuth2Util.getAppInformationByClientId(consumerKey);
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getApplicationResidentOrganizationId();
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
try {
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
.resolveTenantDomain(applicationResidentOrgId);
} catch (OrganizationManagementException e) {
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
+ applicationResidentOrgId, e);
}
}
OAuthAppDO authAppDO = OAuth2Util.getAppInformationByClientId(consumerKey, tenantDomain);
String appState = authAppDO.getState();
if (StringUtils.isEmpty(appState)) {
if (log.isDebugEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
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.base.IdentityConstants;
Expand All @@ -54,6 +55,7 @@
import org.wso2.carbon.identity.openidconnect.CustomClaimsCallbackHandler;
import org.wso2.carbon.identity.openidconnect.OIDCClaimUtil;
import org.wso2.carbon.identity.openidconnect.util.ClaimHandlerUtil;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;

import java.security.Key;
import java.security.cert.Certificate;
Expand Down Expand Up @@ -411,7 +413,11 @@ private String getSigningTenantDomain(String clientID, AuthenticatedUser authent
throws IdentityOAuth2Exception {

String tenantDomain;
if (OAuthServerConfiguration.getInstance().getUseSPTenantDomainValue()) {
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getApplicationResidentOrganizationId();
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
} else if (OAuthServerConfiguration.getInstance().getUseSPTenantDomainValue()) {
if (log.isDebugEnabled()) {
log.debug("Using the tenant domain of the SP to sign the token");
}
Expand Down Expand Up @@ -558,8 +564,20 @@ protected JWTClaimsSet createJWTClaimSet(OAuthAuthzReqMessageContext authAuthzRe

// loading the stored application data
OAuthAppDO oAuthAppDO;
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getApplicationResidentOrganizationId();
try {
oAuthAppDO = OAuth2Util.getAppInformationByClientId(consumerKey);
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
try {
tenantDomain = OAuth2ServiceComponentHolder.getInstance().getOrganizationManager()
.resolveTenantDomain(applicationResidentOrgId);
} catch (OrganizationManagementException e) {
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
+ applicationResidentOrgId, e);
}
}
oAuthAppDO = OAuth2Util.getAppInformationByClientId(consumerKey, tenantDomain);
} catch (InvalidOAuthClientException e) {
throw new IdentityOAuth2Exception("Error while retrieving app information for clientId: " + consumerKey, e);
}
Expand All @@ -576,6 +594,11 @@ protected JWTClaimsSet createJWTClaimSet(OAuthAuthzReqMessageContext authAuthzRe
spTenantDomain = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getTenantDomain();
}

// Need a proper way to handle this.
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
spTenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();;
}

boolean isMTLSrequest;
if (authAuthzReqMessageContext != null) {
/* If the auth request is originated from a request object reference(ex: PAR), then that endpoint should be
Expand Down
Loading

0 comments on commit ecb8ca8

Please sign in to comment.