From 6747f13d2a66c8a2e78e3c8255cf028fe7eefba4 Mon Sep 17 00:00:00 2001 From: Madhavi Gayathri Date: Fri, 11 Oct 2024 15:30:46 +0530 Subject: [PATCH] Replace usages of auth config with app version. --- .../identity/oauth/common/OAuthConstants.java | 2 - .../src/main/resources/OAuthAdminService.wsdl | 1 - .../identity/oauth/OAuthAdminServiceImpl.java | 43 ++++++++++++------- .../wso2/carbon/identity/oauth/OAuthUtil.java | 1 - .../PreIssueAccessTokenRequestBuilder.java | 1 + .../identity/oauth/dao/OAuthAppDAO.java | 21 --------- .../carbon/identity/oauth/dao/OAuthAppDO.java | 11 ----- .../oauth/dto/OAuthConsumerAppDTO.java | 11 ----- .../identity/oauth2/util/OAuth2Util.java | 26 +++++++++-- .../openidconnect/util/ClaimHandlerUtil.java | 28 +++++++++++- 10 files changed, 77 insertions(+), 68 deletions(-) diff --git a/components/org.wso2.carbon.identity.oauth.common/src/main/java/org/wso2/carbon/identity/oauth/common/OAuthConstants.java b/components/org.wso2.carbon.identity.oauth.common/src/main/java/org/wso2/carbon/identity/oauth/common/OAuthConstants.java index 2984f0bd82..7ee3e18fa1 100644 --- a/components/org.wso2.carbon.identity.oauth.common/src/main/java/org/wso2/carbon/identity/oauth/common/OAuthConstants.java +++ b/components/org.wso2.carbon.identity.oauth.common/src/main/java/org/wso2/carbon/identity/oauth/common/OAuthConstants.java @@ -643,8 +643,6 @@ public static class OIDCConfigProperties { public static final String IS_SUBJECT_TOKEN_ENABLED = "isSubjectTokenEnabled"; public static final String SUBJECT_TOKEN_EXPIRY_TIME = "subjectTokenExpiryTime"; public static final int SUBJECT_TOKEN_EXPIRY_TIME_VALUE = 180; - public static final String IS_ACCESS_TOKEN_CLAIMS_SEPARATION_ENABLED = - "isAccessTokenClaimsSeparationEnabled"; public static final String PREVENT_TOKEN_REUSE = "PreventTokenReuse"; public static final boolean DEFAULT_VALUE_FOR_PREVENT_TOKEN_REUSE = true; // Name of the {@code JWTClientAuthenticatorConfig} resource type in the Configuration Management API. diff --git a/components/org.wso2.carbon.identity.oauth.stub/src/main/resources/OAuthAdminService.wsdl b/components/org.wso2.carbon.identity.oauth.stub/src/main/resources/OAuthAdminService.wsdl index 60767786e0..89f6009d95 100755 --- a/components/org.wso2.carbon.identity.oauth.stub/src/main/resources/OAuthAdminService.wsdl +++ b/components/org.wso2.carbon.identity.oauth.stub/src/main/resources/OAuthAdminService.wsdl @@ -395,7 +395,6 @@ - diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java index 878c0450c9..1dbf1fa01b 100755 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java @@ -232,7 +232,7 @@ public OAuthConsumerAppDTO getOAuthApplicationData(String consumerKey, String te OAuthAppDO app = getOAuthApp(consumerKey, tenantDomain); if (app != null) { if (isAccessTokenClaimsSeparationFeatureEnabled() && - !app.isAccessTokenClaimsSeparationEnabled()) { + !isAccessTokenClaimsSeparationEnabledForApp(consumerKey, tenantDomain)) { // Add requested claims as access token claims if the app is not in the new access token // claims feature. addAccessTokenClaims(app, tenantDomain); @@ -536,7 +536,6 @@ OAuthConsumerAppDTO registerAndRetrieveOAuthApplicationData(OAuthConsumerAppDTO if (isAccessTokenClaimsSeparationFeatureEnabled()) { validateAccessTokenClaims(application, tenantDomain); app.setAccessTokenClaims(application.getAccessTokenClaims()); - app.setAccessTokenClaimsSeparationEnabled(true); } } dao.addOAuthApplication(app); @@ -977,27 +976,32 @@ void updateConsumerApplication(OAuthConsumerAppDTO consumerAppDTO, boolean enabl if (isAccessTokenClaimsSeparationFeatureEnabled()) { // We check if the AT claims separation enabled at server level and // the app level. If both are enabled, we validate the claims and update the app. - if (oAuthAppDO.isAccessTokenClaimsSeparationEnabled()) { - validateAccessTokenClaims(consumerAppDTO, tenantDomain); - oAuthAppDO.setAccessTokenClaims(consumerAppDTO.getAccessTokenClaims()); + try { + if (isAccessTokenClaimsSeparationEnabledForApp(oAuthAppDO.getOauthConsumerKey(), tenantDomain)) { + validateAccessTokenClaims(consumerAppDTO, tenantDomain); + oAuthAppDO.setAccessTokenClaims(consumerAppDTO.getAccessTokenClaims()); + } + } catch (IdentityOAuth2Exception e) { + throw new IdentityOAuthAdminException("Error while updating existing OAuth application to " + + "the new JWT access token OIDC claims separation model. Application : " + + oAuthAppDO.getApplicationName() + " Tenant : " + tenantDomain, e); } // We only trigger the access token claims migration if the following conditions are met. // 1. The AT claims separation is enabled at server level. // 2. The AT claims separation is not enabled at app level. - // 3. User tries to enable AT claims separation at app level with update app. - if (!oAuthAppDO.isAccessTokenClaimsSeparationEnabled() && - consumerAppDTO.isAccessTokenClaimsSeparationEnabled()) { - // Add requested claims as access token claims. - try { + // 3. The access token claims are empty. + try { + if (!isAccessTokenClaimsSeparationEnabledForApp(oAuthAppDO.getOauthConsumerKey(), + tenantDomain) && oAuthAppDO.getAccessTokenClaims().length == 0) { + // Add requested claims as access token claims. addAccessTokenClaims(oAuthAppDO, tenantDomain); - } catch (IdentityOAuth2Exception e) { - throw new IdentityOAuthAdminException("Error while updating existing OAuth application to " + - "the new JWT access token OIDC claims separation model. Application : " + - oAuthAppDO.getApplicationName() + " Tenant : " + tenantDomain, e); } + + } catch (IdentityOAuth2Exception e) { + throw new IdentityOAuthAdminException("Error while updating existing OAuth application to " + + "the new JWT access token OIDC claims separation model. Application : " + + oAuthAppDO.getApplicationName() + " Tenant : " + tenantDomain, e); } - oAuthAppDO.setAccessTokenClaimsSeparationEnabled(consumerAppDTO - .isAccessTokenClaimsSeparationEnabled()); } } dao.updateConsumerApplication(oAuthAppDO); @@ -2867,4 +2871,11 @@ private boolean isAccessTokenClaimsSeparationFeatureEnabled() { return Boolean.parseBoolean(IdentityUtil.getProperty(ENABLE_CLAIMS_SEPARATION_FOR_ACCESS_TOKEN)); } + + private boolean isAccessTokenClaimsSeparationEnabledForApp(String consumerKey, String tenantDomain) + throws IdentityOAuth2Exception { + + ServiceProvider serviceProvider = OAuth2Util.getServiceProvider(consumerKey, tenantDomain); + return OAuth2Util.isGivenAppVersionAllowed(serviceProvider.getApplicationVersion(), "v2.0.0"); + } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java index 521d1300c4..f69ee36d17 100755 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java @@ -562,7 +562,6 @@ public static OAuthConsumerAppDTO buildConsumerAppDTO(OAuthAppDO appDO) { dto.setSubjectTokenEnabled(appDO.isSubjectTokenEnabled()); dto.setSubjectTokenExpiryTime(appDO.getSubjectTokenExpiryTime()); dto.setAccessTokenClaims(appDO.getAccessTokenClaims()); - dto.setAccessTokenClaimsSeparationEnabled(appDO.isAccessTokenClaimsSeparationEnabled()); return dto; } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenRequestBuilder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenRequestBuilder.java index 9f88024419..a164e3a76f 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenRequestBuilder.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenRequestBuilder.java @@ -282,6 +282,7 @@ private Map getAdditionalClaimsToAddToToken(OAuthTokenReqMessage } try { + String tenantDomain = tokenMessageContext.getOauth2AccessTokenReqDTO().getTenantDomain(); CustomClaimsCallbackHandler claimsCallBackHandler = ClaimHandlerUtil.getClaimsCallbackHandler(getAppInformation(tokenMessageContext)); JWTClaimsSet claimsSet = diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAO.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAO.java index f11815a74a..bfd3b2b64a 100755 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAO.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAO.java @@ -85,7 +85,6 @@ import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.ID_TOKEN_ENCRYPTION_ALGORITHM; import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.ID_TOKEN_ENCRYPTION_METHOD; import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.ID_TOKEN_SIGNATURE_ALGORITHM; -import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.IS_ACCESS_TOKEN_CLAIMS_SEPARATION_ENABLED; import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.IS_CERTIFICATE_BOUND_ACCESS_TOKEN; import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.IS_FAPI_CONFORMANT_APP; import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.IS_PUSH_AUTH; @@ -1044,13 +1043,6 @@ private void addOrUpdateOIDCSpProperty(OAuthAppDO oauthAppDO, SUBJECT_TOKEN_EXPIRY_TIME, String.valueOf(oauthAppDO.getSubjectTokenExpiryTime()), prepStatementForPropertyAdd, preparedStatementForPropertyUpdate); - if (isAccessTokenClaimsSeparationFeatureEnabled()) { - addOrUpdateOIDCSpProperty(preprocessedClientId, spTenantId, spOIDCProperties, - IS_ACCESS_TOKEN_CLAIMS_SEPARATION_ENABLED, - String.valueOf(oauthAppDO.isAccessTokenClaimsSeparationEnabled()), - prepStatementForPropertyAdd, preparedStatementForPropertyUpdate); - } - addOrUpdateOIDCSpProperty(preprocessedClientId, spTenantId, spOIDCProperties, HYBRID_FLOW_ENABLED, String.valueOf(oauthAppDO.isHybridFlowEnabled()), prepStatementForPropertyAdd, preparedStatementForPropertyUpdate); @@ -1779,12 +1771,6 @@ private void addServiceProviderOIDCProperties(Connection connection, addToBatchForOIDCPropertyAdd(processedClientId, spTenantId, prepStmtAddOIDCProperty, SUBJECT_TOKEN_EXPIRY_TIME, String.valueOf(consumerAppDO.getSubjectTokenExpiryTime())); - if (isAccessTokenClaimsSeparationFeatureEnabled()) { - addToBatchForOIDCPropertyAdd(processedClientId, spTenantId, prepStmtAddOIDCProperty, - IS_ACCESS_TOKEN_CLAIMS_SEPARATION_ENABLED, - String.valueOf(consumerAppDO.isAccessTokenClaimsSeparationEnabled())); - } - addToBatchForOIDCPropertyAdd(processedClientId, spTenantId, prepStmtAddOIDCProperty, HYBRID_FLOW_ENABLED, String.valueOf(consumerAppDO.isHybridFlowEnabled())); @@ -1965,13 +1951,6 @@ private void setSpOIDCProperties(Map> spOIDCProperties, OAu oauthApp.setSubjectTokenExpiryTime(Integer.parseInt(subjectTokenExpiryTime)); } - String isAccessTokenClaimsSeparationEnabled = getFirstPropertyValue(spOIDCProperties, - IS_ACCESS_TOKEN_CLAIMS_SEPARATION_ENABLED); - if (isAccessTokenClaimsSeparationEnabled != null) { - oauthApp.setAccessTokenClaimsSeparationEnabled( - Boolean.parseBoolean(isAccessTokenClaimsSeparationEnabled)); - } - boolean hybridFlowEnabled = Boolean.parseBoolean(getFirstPropertyValue(spOIDCProperties, HYBRID_FLOW_ENABLED)); oauthApp.setHybridFlowEnabled(hybridFlowEnabled); diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDO.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDO.java index 773c8b484f..1d676bee02 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDO.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDO.java @@ -96,7 +96,6 @@ public class OAuthAppDO extends InboundConfigurationProtocol implements Serializ private boolean subjectTokenEnabled; private int subjectTokenExpiryTime; private String[] accessTokenClaims; - private boolean accessTokenClaimsSeparationEnabled; public AuthenticatedUser getAppOwner() { @@ -535,14 +534,4 @@ public void setAccessTokenClaims(String[] accessTokenClaims) { this.accessTokenClaims = accessTokenClaims; } - - public boolean isAccessTokenClaimsSeparationEnabled() { - - return accessTokenClaimsSeparationEnabled; - } - - public void setAccessTokenClaimsSeparationEnabled(boolean accessTokenClaimsSeparationEnabled) { - - this.accessTokenClaimsSeparationEnabled = accessTokenClaimsSeparationEnabled; - } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dto/OAuthConsumerAppDTO.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dto/OAuthConsumerAppDTO.java index fb4e4f2d79..4784b822ad 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dto/OAuthConsumerAppDTO.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dto/OAuthConsumerAppDTO.java @@ -81,7 +81,6 @@ public class OAuthConsumerAppDTO implements InboundProtocolConfigurationDTO { private boolean subjectTokenEnabled; private int subjectTokenExpiryTime; private String[] accessTokenClaims; - private boolean accessTokenClaimsSeparationEnabled; // CORS origin related properties. This will be used by the CORS management service @IgnoreNullElement @@ -540,15 +539,5 @@ public void setAccessTokenClaims(String[] accessTokenClaims) { this.accessTokenClaims = accessTokenClaims; } - - public boolean isAccessTokenClaimsSeparationEnabled() { - - return accessTokenClaimsSeparationEnabled; - } - - public void setAccessTokenClaimsSeparationEnabled(boolean accessTokenClaimsSeparationEnabled) { - - this.accessTokenClaimsSeparationEnabled = accessTokenClaimsSeparationEnabled; - } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java index 68f8820d75..ca3a1168b2 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java @@ -393,8 +393,6 @@ public class OAuth2Util { ApplicationConstants.MY_ACCOUNT_APPLICATION_CLIENT_ID, ApplicationConstants.CONSOLE_APPLICATION_CLIENT_ID); - public static final String ALLOWED_VERSION_TO_STOP_USING_APP_OWNER_FOR_TOKEN_IDENTIFICATION = "v1.0.0"; - private OAuth2Util() { } @@ -5544,10 +5542,11 @@ public static boolean isPairwiseSubEnabledForAccessTokens() { * @param appVersion App version. * @return True if the app version is greater than or equal to the allowed minimum version. */ + @Deprecated public static boolean isAllowedToStopUsingAppOwnerForTokenIdentification(String appVersion) { String[] appVersionDigits = appVersion.substring(1).split("\\."); - String[] allowedVersionDigits = ALLOWED_VERSION_TO_STOP_USING_APP_OWNER_FOR_TOKEN_IDENTIFICATION.substring(1) + String[] allowedVersionDigits = ApplicationConstants.ApplicationVersion.APP_VERSION_V1.substring(1) .split("\\."); for (int i = 0; i < appVersionDigits.length; i++) { @@ -5559,4 +5558,25 @@ public static boolean isAllowedToStopUsingAppOwnerForTokenIdentification(String } return true; } + + /** + * Compare the app version with allowed minimum app version. + * + * @param appVersion App version. + * @return True if the app version is greater than or equal to the allowed minimum app version. + */ + public static boolean isGivenAppVersionAllowed(String appVersion, String allowedAppVersion) { + + String[] appVersionDigits = appVersion.substring(1).split("\\."); + String[] allowedVersionDigits = allowedAppVersion.substring(1).split("\\."); + + for (int i = 0; i < appVersionDigits.length; i++) { + if (appVersionDigits[i].equals(allowedVersionDigits[i])) { + continue; + } else { + return Integer.parseInt(appVersionDigits[i]) >= Integer.parseInt(allowedVersionDigits[i]); + } + } + return true; + } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/util/ClaimHandlerUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/util/ClaimHandlerUtil.java index 0428536266..910c06a1ee 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/util/ClaimHandlerUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/util/ClaimHandlerUtil.java @@ -18,9 +18,13 @@ package org.wso2.carbon.identity.openidconnect.util; +import org.wso2.carbon.identity.application.common.model.ServiceProvider; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; import org.wso2.carbon.identity.oauth.dao.OAuthAppDO; +import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.identity.openidconnect.CustomClaimsCallbackHandler; import static org.wso2.carbon.identity.oauth.common.OAuthConstants.ENABLE_CLAIMS_SEPARATION_FOR_ACCESS_TOKEN; @@ -30,11 +34,21 @@ */ public class ClaimHandlerUtil { - public static CustomClaimsCallbackHandler getClaimsCallbackHandler(OAuthAppDO oAuthAppDO) { + /** + * Get the claims callback handler based on the application configuration. + * + * @param oAuthAppDO OAuth application data object. + * @return CustomClaimsCallbackHandler. + */ + public static CustomClaimsCallbackHandler getClaimsCallbackHandler(OAuthAppDO oAuthAppDO) + throws IdentityOAuth2Exception { // If JWT access token OIDC claims separation is enabled and the application is configured to separate OIDC // claims, use the JWTAccessTokenOIDCClaimsHandler to handle custom claims. - if (isAccessTokenClaimsSeparationFeatureEnabled() && oAuthAppDO.isAccessTokenClaimsSeparationEnabled()) { + int appTenantId = IdentityTenantUtil.getLoginTenantId(); + String tenantDomain = IdentityTenantUtil.getTenantDomain(appTenantId); + if (isAccessTokenClaimsSeparationFeatureEnabled() && + isAccessTokenClaimsSeparationEnabledForApp(oAuthAppDO, tenantDomain)) { return OAuthServerConfiguration.getInstance().getJWTAccessTokenOIDCClaimsHandler(); } return OAuthServerConfiguration.getInstance().getOpenIDConnectCustomClaimsCallbackHandler(); @@ -44,4 +58,14 @@ private static boolean isAccessTokenClaimsSeparationFeatureEnabled() { return Boolean.parseBoolean(IdentityUtil.getProperty(ENABLE_CLAIMS_SEPARATION_FOR_ACCESS_TOKEN)); } + + private static boolean isAccessTokenClaimsSeparationEnabledForApp(OAuthAppDO oAuthAppDO, String tenantDomain) + throws IdentityOAuth2Exception { + + ServiceProvider serviceProvider = OAuth2Util.getServiceProvider(oAuthAppDO.getOauthConsumerKey(), tenantDomain); + String appVersion = serviceProvider.getApplicationVersion(); + + // Todo change to constant. + return OAuth2Util.isGivenAppVersionAllowed(appVersion, "v2.0.0"); + } }