Skip to content

Commit

Permalink
Replace usages of auth config with app version.
Browse files Browse the repository at this point in the history
  • Loading branch information
mpmadhavig committed Oct 11, 2024
1 parent 201592e commit 6747f13
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,6 @@
<xs:sequence>
<xs:element minOccurs="0" name="OAuthVersion" nillable="true" type="xs:string"/>
<xs:element maxOccurs="unbounded" minOccurs="0" name="accessTokenClaims" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="accessTokenClaimsSeparationEnabled" type="xs:boolean"/>
<xs:element minOccurs="0" name="applicationAccessTokenExpiryTime" type="xs:long"/>
<xs:element minOccurs="0" name="applicationName" nillable="true" type="xs:string"/>
<xs:element maxOccurs="unbounded" minOccurs="0" name="audiences" nillable="true" type="xs:string"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -536,7 +536,6 @@ OAuthConsumerAppDTO registerAndRetrieveOAuthApplicationData(OAuthConsumerAppDTO
if (isAccessTokenClaimsSeparationFeatureEnabled()) {
validateAccessTokenClaims(application, tenantDomain);
app.setAccessTokenClaims(application.getAccessTokenClaims());
app.setAccessTokenClaimsSeparationEnabled(true);
}
}
dao.addOAuthApplication(app);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ private Map<String, Object> getAdditionalClaimsToAddToToken(OAuthTokenReqMessage
}

try {
String tenantDomain = tokenMessageContext.getOauth2AccessTokenReqDTO().getTenantDomain();
CustomClaimsCallbackHandler claimsCallBackHandler =
ClaimHandlerUtil.getClaimsCallbackHandler(getAppInformation(tokenMessageContext));
JWTClaimsSet claimsSet =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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()));
Expand Down Expand Up @@ -1965,13 +1951,6 @@ private void setSpOIDCProperties(Map<String, List<String>> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {

Expand Down Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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() {

}
Expand Down Expand Up @@ -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++) {
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
Expand All @@ -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");
}
}

0 comments on commit 6747f13

Please sign in to comment.