Skip to content

Commit a407d88

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

File tree

15 files changed

+229
-20
lines changed

15 files changed

+229
-20
lines changed

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

Lines changed: 17 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,8 @@ public OAuthRevocationResponseDTO revokeTokenByOAuthClient(OAuthRevocationReques
676678

677679
} else if (accessTokenDO != null) {
678680
if (revokeRequestDTO.getConsumerKey().equals(accessTokenDO.getConsumerKey())) {
679-
if ((OAuth2Util.getAppInformationByClientId(accessTokenDO.getConsumerKey()).
681+
String tenantDomain = IdentityTenantUtil.getTenantDomain(accessTokenDO.getTenantID());
682+
if ((OAuth2Util.getAppInformationByClientId(accessTokenDO.getConsumerKey(), tenantDomain).
680683
isTokenBindingValidationEnabled()) && (!isValidTokenBinding(accessTokenDO.
681684
getTokenBinding(), revokeRequestDTO.getRequest()))) {
682685
if (LoggerUtils.isDiagnosticLogsEnabled()) {
@@ -981,7 +984,19 @@ public Claim[] getUserClaims(String accessTokenIdentifier) {
981984
public String getOauthApplicationState(String consumerKey) {
982985

983986
try {
984-
OAuthAppDO appDO = OAuth2Util.getAppInformationByClientId(consumerKey);
987+
String tenantDomain = IdentityTenantUtil.getTenantDomain(IdentityTenantUtil.getLoginTenantId());
988+
String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
989+
.getApplicationResidentOrganizationId();
990+
if (StringUtils.isNotEmpty(appOrgId)) {
991+
try {
992+
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
993+
.resolveTenantDomain(appOrgId);
994+
} catch (OrganizationManagementException e) {
995+
throw new IdentityOAuth2Exception("Error while resolving tenant domain for the organization ID: " +
996+
appOrgId, e);
997+
}
998+
}
999+
OAuthAppDO appDO = OAuth2Util.getAppInformationByClientId(consumerKey, tenantDomain);
9851000
return appDO.getState();
9861001
} catch (IdentityOAuth2Exception e) {
9871002
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: 17 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,20 @@ 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+
if (StringUtils.isNotEmpty(appOrgId)) {
100+
try {
101+
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
102+
.resolveTenantDomain(appOrgId);
103+
} catch (OrganizationManagementException e) {
104+
throw new InvalidOAuthClientException("Error while resolving tenant domain for the organization " +
105+
"ID: " + appOrgId, e);
106+
}
107+
}
92108
return OAuth2Util.authenticateClient(oAuthClientAuthnContext.getClientId(),
93-
(String) oAuthClientAuthnContext.getParameter(OAuth.OAUTH_CLIENT_SECRET));
109+
(String) oAuthClientAuthnContext.getParameter(OAuth.OAUTH_CLIENT_SECRET), tenantDomain);
94110
} catch (IdentityOAuthAdminException e) {
95111
throw new OAuthClientAuthnException("Error while authenticating client",
96112
OAuth2ErrorCodes.INVALID_CLIENT, e);

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

Lines changed: 14 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,17 @@ private List<OAuthClientAuthenticator> getConfiguredClientAuthMethods(String cli
321324
throws OAuthClientAuthnException, InvalidOAuthClientException {
322325

323326
String tenantDomain = IdentityTenantUtil.resolveTenantDomain();
327+
String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
328+
.getApplicationResidentOrganizationId();
329+
if (StringUtils.isNotEmpty(appOrgId)) {
330+
try {
331+
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
332+
.resolveTenantDomain(appOrgId);
333+
} catch (OrganizationManagementException e) {
334+
throw new InvalidOAuthClientException("Error while resolving tenant domain for the organization ID: " +
335+
appOrgId, e);
336+
}
337+
}
324338
List<String> configuredClientAuthMethods = new ArrayList<>();
325339
try {
326340
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: 13 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,18 @@ 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+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
258+
try {
259+
String tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
260+
.resolveTenantDomain(applicationResidentOrgId);
261+
appTenantId = OAuth2Util.getTenantId(tenantDomain);
262+
} catch (OrganizationManagementException e) {
263+
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
264+
+ applicationResidentOrgId, e);
265+
}
266+
}
254267
if (OAuth2ServiceComponentHolder.isIDPIdColumnEnabled()) {
255268
if (OAuth2ServiceComponentHolder.isConsentedTokenColumnEnabled()) {
256269
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: 16 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,20 @@ 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+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
171+
try {
172+
String tenantDomain = OAuth2ServiceComponentHolder.getInstance().getOrganizationManager()
173+
.resolveTenantDomain(applicationResidentOrgId);
174+
tenantId = IdentityTenantUtil.getTenantId(tenantDomain);
175+
} catch (OrganizationManagementException e) {
176+
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
177+
+ applicationResidentOrgId, e);
178+
}
179+
}
180+
prepStmt.setInt(2, tenantId);
167181
if (refreshToken != null) {
168182
prepStmt.setString(3, getHashingPersistenceProcessor().getProcessedRefreshToken(refreshToken));
169183
}
@@ -183,7 +197,7 @@ public RefreshTokenValidationDataDO validateRefreshToken(String consumerKey, Str
183197
validationDataDO.setAccessToken(resultSet.getString(1));
184198
}
185199
String userName = resultSet.getString(2);
186-
int tenantId = resultSet.getInt(3);
200+
tenantId = resultSet.getInt(3);
187201
String userDomain = resultSet.getString(4);
188202
String tenantDomain = OAuth2Util.getTenantDomain(tenantId);
189203
validationDataDO.setRefreshToken(refreshToken);

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

Lines changed: 20 additions & 2 deletions
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;
@@ -167,7 +168,7 @@ public static AccessTokenIssuer getInstance() throws IdentityOAuth2Exception {
167168
public OAuth2AccessTokenRespDTO issue(OAuth2AccessTokenReqDTO tokenReqDTO)
168169
throws IdentityException {
169170

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

173174
AuthorizationGrantHandler authzGrantHandler = authzGrantHandlers.get(grantType);
@@ -308,6 +309,11 @@ 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+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
315+
tokReqMsgCtx.getAuthorizedUser().setAccessingOrganization(applicationResidentOrgId);
316+
}
311317
} else {
312318
tokReqMsgCtx.addProperty(OAuthConstants.UserType.USER_TYPE, OAuthConstants.UserType.APPLICATION_USER);
313319
}
@@ -1361,7 +1367,19 @@ private void setResponseHeaders(OAuthTokenReqMessageContext tokReqMsgCtx,
13611367
private OAuthAppDO getOAuthApplication(String consumerKey) throws InvalidOAuthClientException,
13621368
IdentityOAuth2Exception {
13631369

1364-
OAuthAppDO authAppDO = OAuth2Util.getAppInformationByClientId(consumerKey);
1370+
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
1371+
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
1372+
.getApplicationResidentOrganizationId();
1373+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
1374+
try {
1375+
tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
1376+
.resolveTenantDomain(applicationResidentOrgId);
1377+
} catch (OrganizationManagementException e) {
1378+
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
1379+
+ applicationResidentOrgId, e);
1380+
}
1381+
}
1382+
OAuthAppDO authAppDO = OAuth2Util.getAppInformationByClientId(consumerKey, tenantDomain);
13651383
String appState = authAppDO.getState();
13661384
if (StringUtils.isEmpty(appState)) {
13671385
if (log.isDebugEnabled()) {

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

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.apache.commons.logging.Log;
3636
import org.apache.commons.logging.LogFactory;
3737
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
38+
import org.wso2.carbon.context.PrivilegedCarbonContext;
3839
import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException;
3940
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
4041
import org.wso2.carbon.identity.base.IdentityConstants;
@@ -55,6 +56,7 @@
5556
import org.wso2.carbon.identity.openidconnect.CustomClaimsCallbackHandler;
5657
import org.wso2.carbon.identity.openidconnect.OIDCClaimUtil;
5758
import org.wso2.carbon.identity.openidconnect.util.ClaimHandlerUtil;
59+
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
5860

5961
import java.security.Key;
6062
import java.security.cert.Certificate;
@@ -418,7 +420,11 @@ private String getSigningTenantDomain(String clientID, AuthenticatedUser authent
418420
throws IdentityOAuth2Exception {
419421

420422
String tenantDomain;
421-
if (OAuthServerConfiguration.getInstance().getUseSPTenantDomainValue()) {
423+
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
424+
.getApplicationResidentOrganizationId();
425+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
426+
tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
427+
} else if (OAuthServerConfiguration.getInstance().getUseSPTenantDomainValue()) {
422428
if (log.isDebugEnabled()) {
423429
log.debug("Using the tenant domain of the SP to sign the token");
424430
}
@@ -566,8 +572,20 @@ protected JWTClaimsSet createJWTClaimSet(OAuthAuthzReqMessageContext authAuthzRe
566572

567573
// loading the stored application data
568574
OAuthAppDO oAuthAppDO;
575+
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
576+
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
577+
.getApplicationResidentOrganizationId();
569578
try {
570-
oAuthAppDO = OAuth2Util.getAppInformationByClientId(consumerKey);
579+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
580+
try {
581+
tenantDomain = OAuth2ServiceComponentHolder.getInstance().getOrganizationManager()
582+
.resolveTenantDomain(applicationResidentOrgId);
583+
} catch (OrganizationManagementException e) {
584+
throw new IdentityOAuth2Exception("Error while resolving tenant domain from the organization id: "
585+
+ applicationResidentOrgId, e);
586+
}
587+
}
588+
oAuthAppDO = OAuth2Util.getAppInformationByClientId(consumerKey, tenantDomain);
571589
} catch (InvalidOAuthClientException e) {
572590
throw new IdentityOAuth2Exception("Error while retrieving app information for clientId: " + consumerKey, e);
573591
}
@@ -584,6 +602,11 @@ protected JWTClaimsSet createJWTClaimSet(OAuthAuthzReqMessageContext authAuthzRe
584602
spTenantDomain = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getTenantDomain();
585603
}
586604

605+
// Need a proper way to handle this.
606+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
607+
spTenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();;
608+
}
609+
587610
boolean isMTLSrequest;
588611
if (authAuthzReqMessageContext != null) {
589612
/* If the auth request is originated from a request object reference(ex: PAR), then that endpoint should be

0 commit comments

Comments
 (0)