Skip to content

Commit 388a274

Browse files
Allow sub organization applications to issue tokens to access the resources in sub organizations
1 parent 32cb723 commit 388a274

20 files changed

+373
-39
lines changed

components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/OAuth2Service.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.commons.logging.LogFactory;
2424
import org.apache.oltu.oauth2.common.message.types.GrantType;
2525
import org.owasp.encoder.Encode;
26+
import org.wso2.carbon.context.PrivilegedCarbonContext;
2627
import org.wso2.carbon.core.AbstractAdmin;
2728
import org.wso2.carbon.identity.base.IdentityException;
2829
import org.wso2.carbon.identity.central.log.mgt.utils.LogConstants;
@@ -63,6 +64,7 @@
6364
import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinder;
6465
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
6566
import org.wso2.carbon.identity.openidconnect.model.Constants;
67+
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
6668
import org.wso2.carbon.user.api.Claim;
6769
import org.wso2.carbon.user.core.UserStoreManager;
6870
import org.wso2.carbon.utils.DiagnosticLog;
@@ -676,7 +678,9 @@ public OAuthRevocationResponseDTO revokeTokenByOAuthClient(OAuthRevocationReques
676678

677679
} else if (accessTokenDO != null) {
678680
if (revokeRequestDTO.getConsumerKey().equals(accessTokenDO.getConsumerKey())) {
679-
if ((OAuth2Util.getAppInformationByClientId(accessTokenDO.getConsumerKey()).
681+
// Extracting the application details with consumer key and tenant domain.
682+
String tenantDomain = IdentityTenantUtil.getTenantDomain(accessTokenDO.getTenantID());
683+
if ((OAuth2Util.getAppInformationByClientId(accessTokenDO.getConsumerKey(), tenantDomain).
680684
isTokenBindingValidationEnabled()) && (!isValidTokenBinding(accessTokenDO.
681685
getTokenBinding(), revokeRequestDTO.getRequest()))) {
682686
if (LoggerUtils.isDiagnosticLogsEnabled()) {
@@ -981,7 +985,24 @@ public Claim[] getUserClaims(String accessTokenIdentifier) {
981985
public String getOauthApplicationState(String consumerKey) {
982986

983987
try {
984-
OAuthAppDO appDO = OAuth2Util.getAppInformationByClientId(consumerKey);
988+
String tenantDomain = IdentityTenantUtil.getTenantDomain(IdentityTenantUtil.getLoginTenantId());
989+
String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
990+
.getApplicationResidentOrganizationId();
991+
/*
992+
If appOrgId is not empty, then the request comes for an application which is registered directly in the
993+
organization of the appOrgId. Therefore, we need to resolve the tenant domain of the organization.
994+
*/
995+
if (StringUtils.isNotEmpty(appOrgId)) {
996+
try {
997+
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
998+
.resolveTenantDomain(appOrgId);
999+
} catch (OrganizationManagementException e) {
1000+
throw new IdentityOAuth2Exception("Error while resolving tenant domain for the organization ID: " +
1001+
appOrgId, e);
1002+
}
1003+
}
1004+
// Getting the application information by consumer key and tenant domain.
1005+
OAuthAppDO appDO = OAuth2Util.getAppInformationByClientId(consumerKey, tenantDomain);
9851006
return appDO.getState();
9861007
} catch (IdentityOAuth2Exception e) {
9871008
log.error("Error while finding application state for application with client_id: " + consumerKey, e);

components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/client/authentication/BasicAuthClientAuthenticator.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@
2424
import org.apache.commons.logging.Log;
2525
import org.apache.commons.logging.LogFactory;
2626
import org.apache.oltu.oauth2.common.OAuth;
27+
import org.wso2.carbon.context.PrivilegedCarbonContext;
28+
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
2729
import org.wso2.carbon.identity.oauth.IdentityOAuthAdminException;
2830
import org.wso2.carbon.identity.oauth.common.OAuth2ErrorCodes;
2931
import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthClientException;
32+
import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder;
3033
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
3134
import org.wso2.carbon.identity.oauth2.bean.OAuthClientAuthnContext;
3235
import org.wso2.carbon.identity.oauth2.model.ClientAuthenticationMethodModel;
3336
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
37+
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
3438

3539
import java.util.ArrayList;
3640
import java.util.Base64;
@@ -89,8 +93,25 @@ public boolean authenticateClient(HttpServletRequest request, Map<String, List>
8993
log.debug("Authenticating client : " + oAuthClientAuthnContext.getClientId() + " with client " +
9094
"secret.");
9195
}
96+
String tenantDomain = IdentityTenantUtil.resolveTenantDomain();
97+
String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
98+
.getApplicationResidentOrganizationId();
99+
/*
100+
If appOrgId is not empty, then the request comes for an application which is registered directly in the
101+
organization of the appOrgId. Therefore, we need to resolve the tenant domain of the organization.
102+
*/
103+
if (StringUtils.isNotEmpty(appOrgId)) {
104+
try {
105+
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
106+
.resolveTenantDomain(appOrgId);
107+
} catch (OrganizationManagementException e) {
108+
throw new InvalidOAuthClientException("Error while resolving tenant domain for the organization " +
109+
"ID: " + appOrgId, e);
110+
}
111+
}
112+
// Authenticating the client with the client id, the client secret and the extracted tenant domain.
92113
return OAuth2Util.authenticateClient(oAuthClientAuthnContext.getClientId(),
93-
(String) oAuthClientAuthnContext.getParameter(OAuth.OAUTH_CLIENT_SECRET));
114+
(String) oAuthClientAuthnContext.getParameter(OAuth.OAUTH_CLIENT_SECRET), tenantDomain);
94115
} catch (IdentityOAuthAdminException e) {
95116
throw new OAuthClientAuthnException("Error while authenticating client",
96117
OAuth2ErrorCodes.INVALID_CLIENT, e);

components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/client/authentication/OAuthClientAuthnService.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,19 @@
2121
import org.apache.commons.lang.StringUtils;
2222
import org.apache.commons.logging.Log;
2323
import org.apache.commons.logging.LogFactory;
24+
import org.wso2.carbon.context.PrivilegedCarbonContext;
2425
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
2526
import org.wso2.carbon.identity.core.util.IdentityUtil;
2627
import org.wso2.carbon.identity.oauth.common.OAuth2ErrorCodes;
2728
import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthClientException;
2829
import org.wso2.carbon.identity.oauth.dao.OAuthAppDO;
30+
import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder;
2931
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
3032
import org.wso2.carbon.identity.oauth2.bean.OAuthClientAuthnContext;
3133
import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder;
3234
import org.wso2.carbon.identity.oauth2.model.ClientAuthenticationMethodModel;
3335
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
36+
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
3437

3538
import java.util.ArrayList;
3639
import java.util.Arrays;
@@ -321,6 +324,21 @@ private List<OAuthClientAuthenticator> getConfiguredClientAuthMethods(String cli
321324
throws OAuthClientAuthnException, InvalidOAuthClientException {
322325

323326
String tenantDomain = IdentityTenantUtil.resolveTenantDomain();
327+
String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
328+
.getApplicationResidentOrganizationId();
329+
/*
330+
If appOrgId is not empty, then the request comes for an application which is registered directly in the
331+
organization of the appOrgId. Therefore, we need to resolve the tenant domain of the organization.
332+
*/
333+
if (StringUtils.isNotEmpty(appOrgId)) {
334+
try {
335+
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
336+
.resolveTenantDomain(appOrgId);
337+
} catch (OrganizationManagementException e) {
338+
throw new InvalidOAuthClientException("Error while resolving tenant domain for the organization ID: " +
339+
appOrgId, e);
340+
}
341+
}
324342
List<String> configuredClientAuthMethods = new ArrayList<>();
325343
try {
326344
OAuthAppDO oAuthAppDO = OAuth2Util.getAppInformationByClientId(clientId, tenantDomain);

components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/AccessTokenDAOImpl.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.commons.logging.Log;
2525
import org.apache.commons.logging.LogFactory;
2626
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
27+
import org.wso2.carbon.context.PrivilegedCarbonContext;
2728
import org.wso2.carbon.database.utils.jdbc.JdbcTemplate;
2829
import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException;
2930
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
@@ -251,6 +252,23 @@ private void insertAccessToken(String accessToken, String consumerKey, AccessTok
251252
insertTokenPrepStmt.setString(19, authorizedOrganization);
252253

253254
int appTenantId = IdentityTenantUtil.getLoginTenantId();
255+
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
256+
.getApplicationResidentOrganizationId();
257+
/*
258+
If applicationResidentOrgId is not empty, then the request comes for an application which is registered
259+
directly in the organization of the applicationResidentOrgId. Therefore, we need to resolve the
260+
tenant domain of the organization to get the application tenant id.
261+
*/
262+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
263+
try {
264+
String tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
265+
.resolveTenantDomain(applicationResidentOrgId);
266+
appTenantId = OAuth2Util.getTenantId(tenantDomain);
267+
} catch (OrganizationManagementException e) {
268+
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
269+
+ applicationResidentOrgId, e);
270+
}
271+
}
254272
if (OAuth2ServiceComponentHolder.isIDPIdColumnEnabled()) {
255273
if (OAuth2ServiceComponentHolder.isConsentedTokenColumnEnabled()) {
256274
insertTokenPrepStmt.setString(20, Boolean.toString(accessTokenDO.isConsentedToken()));

components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/TokenManagementDAOImpl.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.commons.lang3.tuple.Pair;
2525
import org.apache.commons.logging.Log;
2626
import org.apache.commons.logging.LogFactory;
27+
import org.wso2.carbon.context.PrivilegedCarbonContext;
2728
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
2829
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
2930
import org.wso2.carbon.identity.application.common.model.ServiceProvider;
@@ -163,7 +164,25 @@ public RefreshTokenValidationDataDO validateRefreshToken(String consumerKey, Str
163164
prepStmt = connection.prepareStatement(sql);
164165

165166
prepStmt.setString(1, getPersistenceProcessor().getProcessedClientId(consumerKey));
166-
prepStmt.setInt(2, IdentityTenantUtil.getLoginTenantId());
167+
int tenantId = IdentityTenantUtil.getLoginTenantId();
168+
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
169+
.getApplicationResidentOrganizationId();
170+
/*
171+
If applicationResidentOrgId is not empty, then the request comes for an application which is registered
172+
directly in the organization of the applicationResidentOrgId. Therefore, we need to resolve the
173+
tenant domain of the organization to get the application tenant id.
174+
*/
175+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
176+
try {
177+
String tenantDomain = OAuth2ServiceComponentHolder.getInstance().getOrganizationManager()
178+
.resolveTenantDomain(applicationResidentOrgId);
179+
tenantId = IdentityTenantUtil.getTenantId(tenantDomain);
180+
} catch (OrganizationManagementException e) {
181+
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
182+
+ applicationResidentOrgId, e);
183+
}
184+
}
185+
prepStmt.setInt(2, tenantId);
167186
if (refreshToken != null) {
168187
prepStmt.setString(3, getHashingPersistenceProcessor().getProcessedRefreshToken(refreshToken));
169188
}
@@ -183,7 +202,7 @@ public RefreshTokenValidationDataDO validateRefreshToken(String consumerKey, Str
183202
validationDataDO.setAccessToken(resultSet.getString(1));
184203
}
185204
String userName = resultSet.getString(2);
186-
int tenantId = resultSet.getInt(3);
205+
tenantId = resultSet.getInt(3);
187206
String userDomain = resultSet.getString(4);
188207
String tenantDomain = OAuth2Util.getTenantDomain(tenantId);
189208
validationDataDO.setRefreshToken(refreshToken);

components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.oltu.oauth2.common.error.OAuthError;
2727
import org.apache.oltu.oauth2.common.message.types.GrantType;
2828
import org.owasp.encoder.Encode;
29+
import org.wso2.carbon.context.PrivilegedCarbonContext;
2930
import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException;
3031
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
3132
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
@@ -308,6 +309,16 @@ public OAuth2AccessTokenRespDTO issue(OAuth2AccessTokenReqDTO tokenReqDTO)
308309
if (!isOfTypeApplicationUser) {
309310
tokReqMsgCtx.setAuthorizedUser(oAuthAppDO.getAppOwner());
310311
tokReqMsgCtx.addProperty(OAuthConstants.UserType.USER_TYPE, OAuthConstants.UserType.APPLICATION);
312+
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
313+
.getApplicationResidentOrganizationId();
314+
/*
315+
If applicationResidentOrgId is not empty, then the request comes for an application which is registered
316+
directly in the organization of the applicationResidentOrgId. Therefore, we are setting the authorized
317+
user's accessing organization as the applicationResidentOrgId.
318+
*/
319+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
320+
tokReqMsgCtx.getAuthorizedUser().setAccessingOrganization(applicationResidentOrgId);
321+
}
311322
} else {
312323
tokReqMsgCtx.addProperty(OAuthConstants.UserType.USER_TYPE, OAuthConstants.UserType.APPLICATION_USER);
313324
}
@@ -1361,7 +1372,21 @@ private void setResponseHeaders(OAuthTokenReqMessageContext tokReqMsgCtx,
13611372
private OAuthAppDO getOAuthApplication(String consumerKey) throws InvalidOAuthClientException,
13621373
IdentityOAuth2Exception {
13631374

1364-
OAuthAppDO authAppDO = OAuth2Util.getAppInformationByClientId(consumerKey);
1375+
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
1376+
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
1377+
.getApplicationResidentOrganizationId();
1378+
// If the applicationResidentOrgId is not null, resolve the tenant domain from the organization id to get the
1379+
// application information by passing the consumer key and the tenant domain.
1380+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
1381+
try {
1382+
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
1383+
.resolveTenantDomain(applicationResidentOrgId);
1384+
} catch (OrganizationManagementException e) {
1385+
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
1386+
+ applicationResidentOrgId, e);
1387+
}
1388+
}
1389+
OAuthAppDO authAppDO = OAuth2Util.getAppInformationByClientId(consumerKey, tenantDomain);
13651390
String appState = authAppDO.getState();
13661391
if (StringUtils.isEmpty(appState)) {
13671392
if (log.isDebugEnabled()) {

0 commit comments

Comments
 (0)