diff --git a/components/org.wso2.carbon.identity.api.server.dcr/pom.xml b/components/org.wso2.carbon.identity.api.server.dcr/pom.xml index 2d07e59d8a4..117417ae74c 100644 --- a/components/org.wso2.carbon.identity.api.server.dcr/pom.xml +++ b/components/org.wso2.carbon.identity.api.server.dcr/pom.xml @@ -23,12 +23,12 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT ../../pom.xml org.wso2.carbon.identity.api.server.dcr - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT WSO2 Carbon - User DCR Rest API WSO2 Carbon - User DCR Rest API diff --git a/components/org.wso2.carbon.identity.api.server.oauth.scope/pom.xml b/components/org.wso2.carbon.identity.api.server.oauth.scope/pom.xml index c1a9e37832b..72d2f71959f 100644 --- a/components/org.wso2.carbon.identity.api.server.oauth.scope/pom.xml +++ b/components/org.wso2.carbon.identity.api.server.oauth.scope/pom.xml @@ -23,12 +23,12 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT ../.. org.wso2.carbon.identity.api.server.oauth.scope - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT WSO2 Carbon - Identity OAuth 2.0 Scope Rest APIs Rest APIs for OAuth 2.0 Scope Handling diff --git a/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml b/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml index 1f54dc0f41e..9d04310e80a 100644 --- a/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml +++ b/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT ../../pom.xml diff --git a/components/org.wso2.carbon.identity.discovery/pom.xml b/components/org.wso2.carbon.identity.discovery/pom.xml index 17608bac0e7..24697d85962 100644 --- a/components/org.wso2.carbon.identity.discovery/pom.xml +++ b/components/org.wso2.carbon.identity.discovery/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.ciba/pom.xml b/components/org.wso2.carbon.identity.oauth.ciba/pom.xml index 0d4f0e98e4b..64e758372dc 100644 --- a/components/org.wso2.carbon.identity.oauth.ciba/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.ciba/pom.xml @@ -20,7 +20,7 @@ identity-inbound-auth-oauth org.wso2.carbon.identity.inbound.auth.oauth2 - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT ../../pom.xml diff --git a/components/org.wso2.carbon.identity.oauth.client.authn.filter/pom.xml b/components/org.wso2.carbon.identity.oauth.client.authn.filter/pom.xml index 9bd489f57b3..3f2ac57623f 100644 --- a/components/org.wso2.carbon.identity.oauth.client.authn.filter/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.client.authn.filter/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.common/pom.xml b/components/org.wso2.carbon.identity.oauth.common/pom.xml index 965a5e120fc..1abfd544874 100644 --- a/components/org.wso2.carbon.identity.oauth.common/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.common/pom.xml @@ -23,7 +23,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 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 7ee3e18fa16..2984f0bd82d 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,6 +643,8 @@ 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.dcr.endpoint/pom.xml b/components/org.wso2.carbon.identity.oauth.dcr.endpoint/pom.xml index fe0d9ea61ea..7bf68f87e07 100644 --- a/components/org.wso2.carbon.identity.oauth.dcr.endpoint/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.dcr.endpoint/pom.xml @@ -6,7 +6,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.dcr/pom.xml b/components/org.wso2.carbon.identity.oauth.dcr/pom.xml index 643d648ff31..aba3b0a37a8 100644 --- a/components/org.wso2.carbon.identity.oauth.dcr/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.dcr/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.endpoint/pom.xml b/components/org.wso2.carbon.identity.oauth.endpoint/pom.xml index 20222c87c3c..69e14b9b339 100644 --- a/components/org.wso2.carbon.identity.oauth.endpoint/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.endpoint/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/jwks/JwksEndpoint.java b/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/jwks/JwksEndpoint.java index b193b1e2035..28e8d1f3ee6 100644 --- a/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/jwks/JwksEndpoint.java +++ b/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/jwks/JwksEndpoint.java @@ -30,15 +30,15 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.core.util.KeyStoreManager; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; -import org.wso2.carbon.identity.core.IdentityKeyStoreResolver; -import org.wso2.carbon.identity.core.util.IdentityKeyStoreResolverConstants; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.oauth.common.OAuthConstants; import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; +import org.wso2.carbon.utils.security.KeystoreUtils; import java.security.KeyStore; import java.security.cert.Certificate; @@ -79,22 +79,21 @@ public String jwks() { try { final KeyStore keystore; - + List certificateInfoList = new ArrayList<>(); if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equalsIgnoreCase(tenantDomain)) { - keystore = IdentityKeyStoreResolver.getInstance().getKeyStore( - tenantDomain, IdentityKeyStoreResolverConstants.InboundProtocol.OAUTH); + KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(MultitenantConstants.SUPER_TENANT_ID); + keystore = keyStoreManager.getPrimaryKeyStore(); } else { try { int tenantId = IdentityTenantUtil.getTenantId(tenantDomain); IdentityTenantUtil.initializeRegistry(tenantId); FrameworkUtils.startTenantFlow(tenantDomain); - keystore = IdentityKeyStoreResolver.getInstance().getKeyStore( - tenantDomain, IdentityKeyStoreResolverConstants.InboundProtocol.OAUTH); + KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(tenantId); + keystore = keyStoreManager.getKeyStore(generateKSNameFromDomainName(tenantDomain)); } finally { FrameworkUtils.endTenantFlow(); } } - List certificateInfoList = new ArrayList<>(); Enumeration enumeration = keystore.aliases(); while (enumeration.hasMoreElements()) { String alias = (String) enumeration.nextElement(); @@ -251,6 +250,16 @@ private String logAndReturnError(String errorMesage, Exception e) { return errorMesage; } + /** + * This method generates the key store file name from the Domain Name. + * + * @return key store file name + */ + private String generateKSNameFromDomainName(String tenantDomain) { + + return KeystoreUtils.getKeyStoreFileLocation(tenantDomain); + } + /** * This method generates the base64 encoded certificate list from a Certificate array. * diff --git a/components/org.wso2.carbon.identity.oauth.endpoint/src/test/java/org/wso2/carbon/identity/oauth/endpoint/jwks/JwksEndpointTest.java b/components/org.wso2.carbon.identity.oauth.endpoint/src/test/java/org/wso2/carbon/identity/oauth/endpoint/jwks/JwksEndpointTest.java index 88fc33e620b..7eb38165df0 100644 --- a/components/org.wso2.carbon.identity.oauth.endpoint/src/test/java/org/wso2/carbon/identity/oauth/endpoint/jwks/JwksEndpointTest.java +++ b/components/org.wso2.carbon.identity.oauth.endpoint/src/test/java/org/wso2/carbon/identity/oauth/endpoint/jwks/JwksEndpointTest.java @@ -31,9 +31,9 @@ import org.testng.annotations.Test; import org.wso2.carbon.base.CarbonBaseConstants; import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.base.ServerConfiguration; +import org.wso2.carbon.core.util.KeyStoreManager; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; -import org.wso2.carbon.identity.core.IdentityKeyStoreResolver; -import org.wso2.carbon.identity.core.util.IdentityKeyStoreResolverConstants; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.oauth.common.OAuthConstants; @@ -44,6 +44,7 @@ import org.wso2.carbon.identity.oauth2.keyidprovider.DefaultKeyIDProviderImpl; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.utils.CarbonUtils; +import org.wso2.carbon.utils.security.KeystoreUtils; import java.io.FileInputStream; import java.lang.reflect.Field; @@ -57,6 +58,7 @@ import java.util.Map; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mockStatic; @@ -67,6 +69,9 @@ @Listeners(MockitoTestNGListener.class) public class JwksEndpointTest { + @Mock + ServerConfiguration serverConfiguration; + @Mock OAuthServerConfiguration mockOAuthServerConfiguration; @@ -74,7 +79,7 @@ public class JwksEndpointTest { TokenPersistenceProcessor tokenPersistenceProcessor; @Mock - IdentityKeyStoreResolver mockIdentityKeyStoreResolver; + KeyStoreManager mockKeyStoreManager; private static final String CERT_THUMB_PRINT = "generatedCertThrumbPrint"; private static final String ALG = "RS256"; @@ -144,16 +149,22 @@ public void testJwks(String tenantDomain, int tenantId) throws Exception { OAuthServerConfiguration.class); MockedStatic carbonUtils = mockStatic(CarbonUtils.class); MockedStatic identityTenantUtil = mockStatic(IdentityTenantUtil.class); - MockedStatic frameworkUtils = mockStatic(FrameworkUtils.class);) { + MockedStatic frameworkUtils = mockStatic(FrameworkUtils.class); + MockedStatic keystoreUtils = mockStatic(KeystoreUtils.class);) { + Path keystorePath = + Paths.get(System.getProperty(CarbonBaseConstants.CARBON_HOME), "repository", "resources", + "security", "wso2carbon.jks"); + keystoreUtils.when(() -> KeystoreUtils.getKeyStoreFileLocation("foo.com")).thenReturn("foo-com.jks"); mockOAuthServerConfiguration(oAuthServerConfiguration); // When the OAuth2Util is mocked, OAuthServerConfiguration instance should be available. try (MockedStatic oAuth2Util = mockStatic(OAuth2Util.class); - MockedStatic identityKeyStoreResolver = - mockStatic(IdentityKeyStoreResolver.class); + MockedStatic keyStoreManager = mockStatic(KeyStoreManager.class); MockedStatic identityUtil = mockStatic(IdentityUtil.class)) { + carbonUtils.when(CarbonUtils::getServerConfiguration).thenReturn(serverConfiguration); + ThreadLocal> threadLocalProperties = new ThreadLocal() { protected Map initialValue() { @@ -207,16 +218,11 @@ protected Map initialValue() { .thenReturn("YmUwN2EzOGI3ZTI0Y2NiNTNmZWFlZjI5Mm" + "VjZjdjZTYzZjI0M2MxNDQ1YjQwNjI3NjYyZmZlYzkwNzY0YjU4NQ"); - identityKeyStoreResolver.when(() -> IdentityKeyStoreResolver.getInstance()) - .thenReturn(mockIdentityKeyStoreResolver); - - lenient().when(mockIdentityKeyStoreResolver - .getKeyStore("carbon.super", IdentityKeyStoreResolverConstants.InboundProtocol.OAUTH)) - .thenReturn(getKeyStoreFromFile("wso2carbon.jks", "wso2carbon")); - lenient().when(mockIdentityKeyStoreResolver - .getKeyStore("foo.com", IdentityKeyStoreResolverConstants.InboundProtocol.OAUTH)) - .thenReturn(getKeyStoreFromFile("foo-com.jks", "foo.com")); - + keyStoreManager.when(() -> KeyStoreManager.getInstance(anyInt())).thenReturn(mockKeyStoreManager); + lenient().when(mockKeyStoreManager.getKeyStore("foo-com.jks")).thenReturn( + getKeyStoreFromFile("foo-com.jks", "foo.com")); + lenient().when(mockKeyStoreManager.getPrimaryKeyStore()).thenReturn( + getKeyStoreFromFile("wso2carbon.jks", "wso2carbon")); identityUtil.when(() -> IdentityUtil.getProperty(ENABLE_X5C_IN_RESPONSE)).thenReturn("true"); String result = jwksEndpoint.jwks(); diff --git a/components/org.wso2.carbon.identity.oauth.extension/pom.xml b/components/org.wso2.carbon.identity.oauth.extension/pom.xml index 44479601bd3..ffbf78c77d4 100644 --- a/components/org.wso2.carbon.identity.oauth.extension/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.extension/pom.xml @@ -19,7 +19,7 @@ identity-inbound-auth-oauth org.wso2.carbon.identity.inbound.auth.oauth2 - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.par/pom.xml b/components/org.wso2.carbon.identity.oauth.par/pom.xml index dc0fbb37849..57607a1ebe1 100644 --- a/components/org.wso2.carbon.identity.oauth.par/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.par/pom.xml @@ -23,7 +23,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.scope.endpoint/pom.xml b/components/org.wso2.carbon.identity.oauth.scope.endpoint/pom.xml index 7930f876ced..4fca7f27592 100644 --- a/components/org.wso2.carbon.identity.oauth.scope.endpoint/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.scope.endpoint/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.stub/pom.xml b/components/org.wso2.carbon.identity.oauth.stub/pom.xml index 4fc20cf4564..612516f084b 100644 --- a/components/org.wso2.carbon.identity.oauth.stub/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.stub/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 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 89f6009d954..60767786e08 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,6 +395,7 @@ + diff --git a/components/org.wso2.carbon.identity.oauth.ui/pom.xml b/components/org.wso2.carbon.identity.oauth.ui/pom.xml index c7206a44caf..2ca29b86aaf 100644 --- a/components/org.wso2.carbon.identity.oauth.ui/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.ui/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth/pom.xml b/components/org.wso2.carbon.identity.oauth/pom.xml index c33a9ba487d..a51c59e1287 100644 --- a/components/org.wso2.carbon.identity.oauth/pom.xml +++ b/components/org.wso2.carbon.identity.oauth/pom.xml @@ -23,7 +23,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 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 1d75ab5aa3b..878c0450c9d 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() && - !isAccessTokenClaimsSeparationEnabledForApp(consumerKey, tenantDomain)) { + !app.isAccessTokenClaimsSeparationEnabled()) { // Add requested claims as access token claims if the app is not in the new access token // claims feature. addAccessTokenClaims(app, tenantDomain); @@ -536,6 +536,7 @@ OAuthConsumerAppDTO registerAndRetrieveOAuthApplicationData(OAuthConsumerAppDTO if (isAccessTokenClaimsSeparationFeatureEnabled()) { validateAccessTokenClaims(application, tenantDomain); app.setAccessTokenClaims(application.getAccessTokenClaims()); + app.setAccessTokenClaimsSeparationEnabled(true); } } dao.addOAuthApplication(app); @@ -976,32 +977,27 @@ 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. - 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); + if (oAuthAppDO.isAccessTokenClaimsSeparationEnabled()) { + validateAccessTokenClaims(consumerAppDTO, tenantDomain); + oAuthAppDO.setAccessTokenClaims(consumerAppDTO.getAccessTokenClaims()); } // 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. The access token claims are empty. - try { - if (!isAccessTokenClaimsSeparationEnabledForApp(oAuthAppDO.getOauthConsumerKey(), - tenantDomain) && oAuthAppDO.getAccessTokenClaims().length == 0) { - // Add requested claims as access token claims. + // 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 { 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); @@ -2871,12 +2867,4 @@ 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.isAppVersionAllowed(serviceProvider.getApplicationVersion(), - ApplicationConstants.ApplicationVersion.APP_VERSION_V2); - } } 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 4cf88072dcf..521d1300c4a 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 @@ -94,7 +94,6 @@ import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.CURRENT_SESSION_IDENTIFIER; import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.CURRENT_TOKEN_IDENTIFIER; import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.Config.PRESERVE_LOGGED_IN_SESSION_AT_PASSWORD_UPDATE; -import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.OAUTH2; import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.ORGANIZATION_LOGIN_HOME_REALM_IDENTIFIER; import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.DEFAULT_VALUE_FOR_PREVENT_TOKEN_REUSE; import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCConfigProperties.ENABLE_TOKEN_REUSE; @@ -563,6 +562,7 @@ public static OAuthConsumerAppDTO buildConsumerAppDTO(OAuthAppDO appDO) { dto.setSubjectTokenEnabled(appDO.isSubjectTokenEnabled()); dto.setSubjectTokenExpiryTime(appDO.getSubjectTokenExpiryTime()); dto.setAccessTokenClaims(appDO.getAccessTokenClaims()); + dto.setAccessTokenClaimsSeparationEnabled(appDO.isAccessTokenClaimsSeparationEnabled()); return dto; } @@ -822,27 +822,6 @@ private static Set getClientIdsOfAssociatedApplications(Role role, Authe return clientIds; } - private static Set filterClientIdsWithOrganizationAudience(List clientIds, String tenantDomain) { - - Set clientIdsWithOrganizationAudience = new HashSet<>(); - ApplicationManagementService applicationManagementService = - OAuthComponentServiceHolder.getInstance().getApplicationManagementService(); - for (String clientId : clientIds) { - try { - String applicationId = applicationManagementService.getApplicationResourceIDByInboundKey(clientId, - OAUTH2, tenantDomain); - String audience = applicationManagementService.getAllowedAudienceForRoleAssociation(applicationId, - tenantDomain); - if (RoleConstants.ORGANIZATION.equalsIgnoreCase(audience)) { - clientIdsWithOrganizationAudience.add(clientId); - } - } catch (IdentityApplicationManagementException e) { - LOG.error("Error occurred while retrieving application information for client id: " + clientId, e); - } - } - return clientIdsWithOrganizationAudience; - } - /** * This method will retrieve the role details of the given role id. * @param roleId Role Id. @@ -1012,7 +991,7 @@ public static boolean revokeTokens(String username, UserStoreManager userStoreMa // Get details about the role to identify the audience and associated applications. Set clientIds = null; - Role role = null; + Role role; boolean getClientIdsFromUser = false; if (roleId != null) { role = getRole(roleId, IdentityTenantUtil.getTenantDomain(userStoreManager.getTenantId())); @@ -1030,7 +1009,6 @@ public static boolean revokeTokens(String username, UserStoreManager userStoreMa "an organization role: " + role.getName()); } getClientIdsFromUser = true; - } } else { // Get all the distinct client Ids authorized by this user since no role is specified. @@ -1044,12 +1022,7 @@ public static boolean revokeTokens(String username, UserStoreManager userStoreMa } try { clientIds = OAuthTokenPersistenceFactory.getInstance() - .getTokenManagementDAO().getAllTimeAuthorizedClientIds(authenticatedUser); - - if (role != null && RoleConstants.ORGANIZATION.equals(role.getAudience())) { - clientIds = filterClientIdsWithOrganizationAudience(new ArrayList<>(clientIds), tenantDomain); - } - + .getTokenManagementDAO().getAllTimeAuthorizedClientIds(authenticatedUser); } catch (IdentityOAuth2Exception e) { LOG.error("Error occurred while retrieving apps authorized by User ID : " + authenticatedUser, e); throw new UserStoreException(e); 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 old mode 100755 new mode 100644 diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenResponseProcessor.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenResponseProcessor.java index f56fa00b26b..2b6d915718a 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenResponseProcessor.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenResponseProcessor.java @@ -133,7 +133,7 @@ private void logOperationExecutionResults(ActionType actionType, ActionExecutionLogConstants.ActionIDs.EXECUTE_ACTION_OPERATIONS); diagLogBuilder .inputParam("executed operations", operationDetailsList.isEmpty() ? "empty" : operationDetailsList) - .resultMessage("Allowed operations are executed for " + actionType.getDisplayName() + " action.") + .resultMessage("Allowed operations are executed for " + actionType + " action.") .logDetailLevel(DiagnosticLog.LogDetailLevel.APPLICATION) .resultStatus(DiagnosticLog.ResultStatus.SUCCESS) .build(); diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java index 89164caa086..372f332e428 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCache.java @@ -18,6 +18,8 @@ package org.wso2.carbon.identity.oauth.cache; +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTParser; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; @@ -29,10 +31,10 @@ import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.dao.OAuthTokenPersistenceFactory; -import org.wso2.carbon.identity.oauth2.model.AccessTokenDO; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.utils.CarbonUtils; +import java.text.ParseException; import java.util.concurrent.TimeUnit; /** @@ -237,11 +239,20 @@ private String replaceFromCodeId(String authzCode) { * @return TOKEN_ID from the database */ private String replaceFromTokenId(String keyValue) { - try { - AccessTokenDO accessTokenDO = OAuth2Util.findAccessToken(keyValue, true); - if (accessTokenDO != null) { - return accessTokenDO.getTokenId(); + + if (OAuth2Util.isJWT(keyValue)) { + try { + JWT parsedJwtToken = JWTParser.parse(keyValue); + keyValue = parsedJwtToken.getJWTClaimsSet().getJWTID(); + } catch (ParseException e) { + if (log.isDebugEnabled() && IdentityUtil.isTokenLoggable( + IdentityConstants.IdentityTokens.ACCESS_TOKEN)) { + log.debug("Error while getting JWTID from token: " + keyValue, e); + } } + } + try { + return OAuthTokenPersistenceFactory.getInstance().getAccessTokenDAO().getTokenIdByAccessToken(keyValue); } catch (IdentityOAuth2Exception e) { log.error("Failed to retrieve token id by token from store for - ." + keyValue, e); } 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 bfd3b2b64a0..f11815a74a4 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,6 +85,7 @@ 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; @@ -1043,6 +1044,13 @@ 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); @@ -1771,6 +1779,12 @@ 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())); @@ -1951,6 +1965,13 @@ 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 1d676bee02d..773c8b484f0 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,6 +96,7 @@ public class OAuthAppDO extends InboundConfigurationProtocol implements Serializ private boolean subjectTokenEnabled; private int subjectTokenExpiryTime; private String[] accessTokenClaims; + private boolean accessTokenClaimsSeparationEnabled; public AuthenticatedUser getAppOwner() { @@ -534,4 +535,14 @@ 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 4784b822ad1..fb4e4f2d795 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,6 +81,7 @@ 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 @@ -539,5 +540,15 @@ 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/authcontext/JWTTokenGenerator.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authcontext/JWTTokenGenerator.java index db4d6a5f989..e370e2021fd 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authcontext/JWTTokenGenerator.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authcontext/JWTTokenGenerator.java @@ -31,10 +31,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.core.util.KeyStoreManager; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.core.IdentityKeyStoreResolver; +import org.wso2.carbon.identity.base.IdentityException; import org.wso2.carbon.identity.core.util.IdentityCoreConstants; -import org.wso2.carbon.identity.core.util.IdentityKeyStoreResolverConstants; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthClientException; import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; @@ -59,8 +60,10 @@ import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.util.UserCoreUtil; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import org.wso2.carbon.utils.security.KeystoreUtils; import java.security.Key; +import java.security.KeyStore; import java.security.MessageDigest; import java.security.cert.Certificate; import java.security.interfaces.RSAPrivateKey; @@ -69,10 +72,12 @@ import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.SortedMap; import java.util.StringTokenizer; import java.util.TreeSet; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; /** * This class represents the JSON Web Token generator. @@ -100,6 +105,9 @@ public class JWTTokenGenerator implements AuthorizationContextTokenGenerator { private boolean enableSigning = true; + private static Map privateKeys = new ConcurrentHashMap(); + private static Map publicCerts = new ConcurrentHashMap(); + private ClaimCache claimsLocalCache; public JWTTokenGenerator() { @@ -311,8 +319,7 @@ protected SignedJWT signJWTWithRSA(SignedJWT signedJWT, JWSAlgorithm jwsAlgorith int tenantId) throws IdentityOAuth2Exception { try { - Key privateKey = IdentityKeyStoreResolver.getInstance() - .getPrivateKey(tenantDomain, IdentityKeyStoreResolverConstants.InboundProtocol.OAUTH); + Key privateKey = getPrivateKey(tenantDomain, tenantId); JWSSigner signer = OAuth2Util.createJWSSigner((RSAPrivateKey) privateKey); signedJWT.sign(signer); return signedJWT; @@ -400,8 +407,8 @@ private long getTTL() { private String getThumbPrint(String tenantDomain, int tenantId) throws IdentityOAuth2Exception { try { - Certificate certificate = IdentityKeyStoreResolver.getInstance() - .getCertificate(tenantDomain, IdentityKeyStoreResolverConstants.InboundProtocol.OAUTH); + + Certificate certificate = getCertificate(tenantDomain, tenantId); // TODO: maintain a hashmap with tenants' pubkey thumbprints after first initialization @@ -422,6 +429,94 @@ private String getThumbPrint(String tenantDomain, int tenantId) throws IdentityO } } + private Key getPrivateKey(String tenantDomain, int tenantId) throws IdentityOAuth2Exception { + + if (tenantDomain == null) { + tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; + } + + if (tenantId == 0) { + tenantId = OAuth2Util.getTenantId(tenantDomain); + } + + Key privateKey = null; + + if (!(privateKeys.containsKey(tenantId))) { + + try { + IdentityTenantUtil.initializeRegistry(tenantId, tenantDomain); + } catch (IdentityException e) { + throw new IdentityOAuth2Exception("Error occurred while loading registry for tenant " + tenantDomain, + e); + } + + // get tenant's key store manager + KeyStoreManager tenantKSM = KeyStoreManager.getInstance(tenantId); + + if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + // derive key store name + String fileName = KeystoreUtils.getKeyStoreFileLocation(tenantDomain); + // obtain private key + privateKey = tenantKSM.getPrivateKey(fileName, tenantDomain); + + } else { + try { + privateKey = tenantKSM.getDefaultPrivateKey(); + } catch (Exception e) { + log.error("Error while obtaining private key for super tenant", e); + } + } + if (privateKey != null) { + privateKeys.put(tenantId, privateKey); + } + } else { + privateKey = privateKeys.get(tenantId); + } + return privateKey; + } + + private Certificate getCertificate(String tenantDomain, int tenantId) throws Exception { + + if (tenantDomain == null) { + tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; + } + + if (tenantId == 0) { + tenantId = OAuth2Util.getTenantId(tenantDomain); + } + + Certificate publicCert = null; + + if (!(publicCerts.containsKey(tenantId))) { + + try { + IdentityTenantUtil.initializeRegistry(tenantId, tenantDomain); + } catch (IdentityException e) { + throw new IdentityOAuth2Exception("Error occurred while loading registry for tenant " + tenantDomain, + e); + } + + // get tenant's key store manager + KeyStoreManager tenantKSM = KeyStoreManager.getInstance(tenantId); + + KeyStore keyStore = null; + if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + // derive key store name + String fileName = KeystoreUtils.getKeyStoreFileLocation(tenantDomain); + keyStore = tenantKSM.getKeyStore(fileName); + publicCert = keyStore.getCertificate(tenantDomain); + } else { + publicCert = tenantKSM.getDefaultPrimaryCertificate(); + } + if (publicCert != null) { + publicCerts.put(tenantId, publicCert); + } + } else { + publicCert = publicCerts.get(tenantId); + } + return publicCert; + } + /** * Helper method to hexify a byte array. * TODO:need to verify the logic diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/device/errorcodes/DeviceErrorCodes.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/device/errorcodes/DeviceErrorCodes.java index 64180640fa4..277e1a92c93 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/device/errorcodes/DeviceErrorCodes.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/device/errorcodes/DeviceErrorCodes.java @@ -50,7 +50,6 @@ public static class SubDeviceErrorCodesDescriptions { public static final String SLOW_DOWN = "Forbidden"; public static final String AUTHORIZATION_PENDING = "Precondition required"; public static final String EXPIRED_TOKEN = "Forbidden"; - public static final String NOT_EXIST = "The provided device code is not registered or is invalid."; } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/device/grant/DeviceFlowGrant.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/device/grant/DeviceFlowGrant.java index c1439c4c747..4d780bf57e2 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/device/grant/DeviceFlowGrant.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/device/grant/DeviceFlowGrant.java @@ -100,8 +100,7 @@ private void handleInvalidRequests(String deviceStatus, DeviceFlowDO deviceFlowD Date date = new Date(); if (Constants.NOT_EXIST.equals(deviceStatus)) { - throw new IdentityOAuth2Exception(DeviceErrorCodes.INVALID_REQUEST, - DeviceErrorCodes.SubDeviceErrorCodesDescriptions.NOT_EXIST); + throw new IdentityOAuth2Exception(DeviceErrorCodes.INVALID_REQUEST, DeviceErrorCodes.INVALID_REQUEST); } else if (Constants.EXPIRED.equals(deviceStatus) || isExpiredDeviceCode(deviceFlowDO, date)) { throw new IdentityOAuth2Exception(DeviceErrorCodes.SubDeviceErrorCodes.EXPIRED_TOKEN, DeviceErrorCodes.SubDeviceErrorCodesDescriptions.EXPIRED_TOKEN); diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java index 16f539f4ec4..c77aa705989 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java @@ -34,7 +34,6 @@ import org.wso2.carbon.identity.application.common.model.ServiceProvider; import org.wso2.carbon.identity.application.common.model.ServiceProviderProperty; import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants; -import org.wso2.carbon.identity.application.mgt.ApplicationConstants; import org.wso2.carbon.identity.base.IdentityConstants; import org.wso2.carbon.identity.base.IdentityException; import org.wso2.carbon.identity.central.log.mgt.utils.LogConstants; @@ -460,9 +459,8 @@ private OAuth2AccessTokenRespDTO validateGrantAndIssueToken(OAuth2AccessTokenReq ServiceProvider serviceProvider = getServiceProvider(tokReqMsgCtx.getOauth2AccessTokenReqDTO()); boolean useClientIdAsSubClaimForAppTokensEnabledServerConfig = OAuthServerConfiguration.getInstance() .isUseClientIdAsSubClaimForAppTokensEnabled(); - boolean useClientIdAsSubClaimForAppTokensEnabled = - OAuth2Util.isAppVersionAllowed(serviceProvider.getApplicationVersion(), - ApplicationConstants.ApplicationVersion.APP_VERSION_V1); + boolean useClientIdAsSubClaimForAppTokensEnabled = OAuth2Util + .isAllowedToStopUsingAppOwnerForTokenIdentification(serviceProvider.getApplicationVersion()); if (authorizedUser.getAuthenticatedSubjectIdentifier() == null) { if ((!isOfTypeApplicationUser && (useClientIdAsSubClaimForAppTokensEnabled || useClientIdAsSubClaimForAppTokensEnabledServerConfig))) { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/JWTTokenIssuer.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/JWTTokenIssuer.java index c7ac52fedb6..6a80d030efb 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/JWTTokenIssuer.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/JWTTokenIssuer.java @@ -38,6 +38,7 @@ 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; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.oauth.common.OAuthConstants; import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthClientException; @@ -458,16 +459,17 @@ protected String signJWTWithRSA(JWTClaimsSet jwtClaimsSet, OAuthTokenReqMessageC try { String tenantDomain = resolveSigningTenantDomain(tokenContext, authorizationContext); + int tenantId = IdentityTenantUtil.getTenantId(tenantDomain); // Add claim with signer tenant to jwt claims set. jwtClaimsSet = setSignerRealm(tenantDomain, jwtClaimsSet); - Key privateKey = getPrivateKey(tenantDomain); + Key privateKey = getPrivateKey(tenantDomain, tenantId); JWSSigner signer = OAuth2Util.createJWSSigner((RSAPrivateKey) privateKey); JWSHeader.Builder headerBuilder = new JWSHeader.Builder((JWSAlgorithm) signatureAlgorithm); - Certificate certificate = OAuth2Util.getCertificate(tenantDomain); + Certificate certificate = OAuth2Util.getCertificate(tenantDomain, tenantId); String certThumbPrint = OAuth2Util.getThumbPrintWithPrevAlgorithm(certificate, false); - headerBuilder.keyID(OAuth2Util.getKID(OAuth2Util.getCertificate(tenantDomain), + headerBuilder.keyID(OAuth2Util.getKID(OAuth2Util.getCertificate(tenantDomain, tenantId), (JWSAlgorithm) signatureAlgorithm, tenantDomain)); if (authorizationContext != null && authorizationContext.isSubjectTokenFlow()) { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/JWTUtils.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/JWTUtils.java index 627c1de8e23..af002c3fdc3 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/JWTUtils.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/JWTUtils.java @@ -468,12 +468,8 @@ public static X509Certificate resolveSignerCertificate(IdentityProvider idp) thr X509Certificate x509Certificate; String tenantDomain = getTenantDomain(); try { - if (IdentityApplicationConstants.RESIDENT_IDP_RESERVED_NAME.equals(idp.getIdentityProviderName())) { - x509Certificate = (X509Certificate) OAuth2Util.getCertificate(tenantDomain); - } else { - x509Certificate = (X509Certificate) IdentityApplicationManagementUtil - .decodeCertificate(idp.getCertificate()); - } + x509Certificate = (X509Certificate) IdentityApplicationManagementUtil + .decodeCertificate(idp.getCertificate()); } catch (CertificateException e) { throw new IdentityOAuth2Exception("Error occurred while decoding public certificate of Identity Provider " + idp.getIdentityProviderName() + " for tenant domain " + tenantDomain, e); 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 28723e3c8c3..52e1855fdb5 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 @@ -64,6 +64,7 @@ import org.json.JSONException; import org.json.JSONObject; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.util.KeyStoreManager; import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; import org.wso2.carbon.identity.application.authentication.framework.exception.UserSessionException; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; @@ -84,14 +85,11 @@ import org.wso2.carbon.identity.central.log.mgt.utils.LogConstants; import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils; import org.wso2.carbon.identity.consent.server.configs.mgt.exceptions.ConsentServerConfigsMgtException; -import org.wso2.carbon.identity.core.IdentityKeyStoreResolver; import org.wso2.carbon.identity.core.ServiceURLBuilder; import org.wso2.carbon.identity.core.URLBuilderException; import org.wso2.carbon.identity.core.util.IdentityConfigParser; import org.wso2.carbon.identity.core.util.IdentityCoreConstants; import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; -import org.wso2.carbon.identity.core.util.IdentityKeyStoreResolverConstants; -import org.wso2.carbon.identity.core.util.IdentityKeyStoreResolverException; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.oauth.IdentityOAuthAdminException; @@ -162,6 +160,7 @@ import org.wso2.carbon.utils.DiagnosticLog; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import org.wso2.carbon.utils.security.KeystoreUtils; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -170,6 +169,8 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; @@ -192,6 +193,7 @@ import java.util.Optional; import java.util.Set; import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -348,6 +350,9 @@ public class OAuth2Util { // System flag to allow the weak keys (key length less than 2048) to be used for the signing. private static final String ALLOW_WEAK_RSA_SIGNER_KEY = "allow_weak_rsa_signer_key"; + private static Map publicCerts = new ConcurrentHashMap(); + private static Map privateKeys = new ConcurrentHashMap(); + // Supported Signature Algorithms private static final String NONE = "NONE"; private static final String SHA256_WITH_RSA = "SHA256withRSA"; @@ -388,6 +393,8 @@ 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() { } @@ -2827,8 +2834,16 @@ public static boolean validateIdToken(String idToken) { return false; } int tenantId = IdentityTenantUtil.getTenantId(tenantDomain); - RSAPublicKey publicKey = IdentityKeyStoreResolver.getInstance() - .getPublicKey(tenantDomain, IdentityKeyStoreResolverConstants.InboundProtocol.OAUTH); + RSAPublicKey publicKey; + KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(tenantId); + + if (!tenantDomain.equals(org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + String fileName = KeystoreUtils.getKeyStoreFileLocation(tenantDomain); + publicKey = (RSAPublicKey) keyStoreManager.getKeyStore(fileName).getCertificate(tenantDomain) + .getPublicKey(); + } else { + publicKey = (RSAPublicKey) keyStoreManager.getDefaultPublicKey(); + } SignedJWT signedJWT = SignedJWT.parse(idToken); JWSVerifier verifier = new RSASSAVerifier(publicKey); @@ -3344,34 +3359,42 @@ public static JWT signJWTWithRSA(JWTClaimsSet jwtClaimsSet, JWSAlgorithm signatu } } - /** - * Method to obatin Default Private key for OAuth2 protocol. - * - * @param tenantDomain Tenant Domain as a String. - * @return Default Private key for OAuth2 protocol. - * @throws IdentityOAuth2Exception When failed to obtain the private key for the requested tenant. - */ - public static Key getPrivateKey(String tenantDomain) throws IdentityOAuth2Exception { + public static Key getPrivateKey(String tenantDomain, int tenantId) throws IdentityOAuth2Exception { - try { - return IdentityKeyStoreResolver.getInstance().getPrivateKey( - tenantDomain, IdentityKeyStoreResolverConstants.InboundProtocol.OAUTH); - } catch (IdentityKeyStoreResolverException e) { - throw new IdentityOAuth2Exception("Error while obtaining private key", e); - } - } + Key privateKey; + if (!(privateKeys.containsKey(tenantId))) { - /** - * Method to obatin Default Private key for OAuth2 protocol. - * - * @param tenantDomain Tenant Domain as a String. - * @param tenantId Tenan ID as an integer. - * @return Default Private key for OAuth2 protocol. - * @throws IdentityOAuth2Exception When failed to obtain the private key for the requested tenant. - */ - public static Key getPrivateKey(String tenantDomain, int tenantId) throws IdentityOAuth2Exception { + try { + IdentityTenantUtil.initializeRegistry(tenantId, tenantDomain); + } catch (IdentityException e) { + throw new IdentityOAuth2Exception("Error occurred while loading registry for tenant " + tenantDomain, + e); + } + + // get tenant's key store manager + KeyStoreManager tenantKSM = KeyStoreManager.getInstance(tenantId); + + if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + // derive key store name + String fileName = KeystoreUtils.getKeyStoreFileLocation(tenantDomain); + // obtain private key + privateKey = tenantKSM.getPrivateKey(fileName, tenantDomain); - return getPrivateKey(tenantDomain); + } else { + try { + privateKey = tenantKSM.getDefaultPrivateKey(); + } catch (Exception e) { + throw new IdentityOAuth2Exception("Error while obtaining private key for super tenant", e); + } + } + //privateKey will not be null always + privateKeys.put(tenantId, privateKey); + } else { + //privateKey will not be null because containsKey() true says given key is exist and ConcurrentHashMap + // does not allow to store null values + privateKey = privateKeys.get(tenantId); + } + return privateKey; } /** @@ -3519,34 +3542,66 @@ private static boolean isRSAAlgorithm(JWEAlgorithm algorithm) { JWEAlgorithm.RSA_OAEP_256.equals(algorithm)); } - /** - * Method to obatin Default Signing certificate for the tenant. - * - * @param tenantDomain Tenant Domain as a String. - * @return Default Signing Certificate of the tenant domain for the OAuth2 protocol. - * @throws IdentityOAuth2Exception When failed to obtain the certificate for the requested tenant. - */ - public static Certificate getCertificate(String tenantDomain) throws IdentityOAuth2Exception { - - try { - return IdentityKeyStoreResolver.getInstance().getCertificate( - tenantDomain, IdentityKeyStoreResolverConstants.InboundProtocol.OAUTH); - } catch (IdentityKeyStoreResolverException e) { - throw new IdentityOAuth2Exception("Error while obtaining public certificate.", e); - } - } - /** * Method to obatin Default Signing certificate for the tenant. * * @param tenantDomain Tenant Domain as a String. * @param tenantId Tenan ID as an integer. - * @return Default Signing Certificate of the tenant domain for the OAuth2 protocol. + * @return Default Signing Certificate of the tenant domain. * @throws IdentityOAuth2Exception When failed to obtain the certificate for the requested tenant. */ public static Certificate getCertificate(String tenantDomain, int tenantId) throws IdentityOAuth2Exception { - return getCertificate(tenantDomain); + Certificate publicCert = null; + + if (!(publicCerts.containsKey(tenantId))) { + if (log.isDebugEnabled()) { + log.debug(String.format("Obtaining certificate for the tenant %s", tenantDomain)); + } + try { + IdentityTenantUtil.initializeRegistry(tenantId, tenantDomain); + } catch (IdentityException e) { + throw new IdentityOAuth2Exception("Error occurred while loading registry for tenant " + tenantDomain, + e); + } + + // get tenant's key store manager + KeyStoreManager tenantKSM = KeyStoreManager.getInstance(tenantId); + + KeyStore keyStore = null; + if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + // derive key store name + String fileName = KeystoreUtils.getKeyStoreFileLocation(tenantDomain); + if (log.isDebugEnabled()) { + log.debug(String.format("Loading default tenant certificate for tenant : %s from the KeyStore" + + " %s", tenantDomain, fileName)); + } + try { + keyStore = tenantKSM.getKeyStore(fileName); + publicCert = keyStore.getCertificate(tenantDomain); + } catch (KeyStoreException e) { + throw new IdentityOAuth2Exception("Error occurred while loading public certificate for tenant: " + + tenantDomain, e); + } catch (Exception e) { + throw new IdentityOAuth2Exception("Error occurred while loading Keystore for tenant: " + + tenantDomain, e); + } + + } else { + try { + publicCert = tenantKSM.getDefaultPrimaryCertificate(); + } catch (Exception e) { + throw new IdentityOAuth2Exception("Error occurred while loading default public " + + "certificate for tenant: " + tenantDomain, e); + } + } + if (publicCert != null) { + publicCerts.put(tenantId, publicCert); + } + } else { + publicCert = publicCerts.get(tenantId); + } + return publicCert; } /** @@ -5574,15 +5629,16 @@ public static boolean isPairwiseSubEnabledForAccessTokens() { } /** - * Compare the app version with allowed minimum app version. + * Compare the app version with allowed minimum version. * * @param appVersion App version. - * @return True if the app version is greater than or equal to the allowed minimum app version. + * @return True if the app version is greater than or equal to the allowed minimum version. */ - public static boolean isAppVersionAllowed(String appVersion, String allowedAppVersion) { + public static boolean isAllowedToStopUsingAppOwnerForTokenIdentification(String appVersion) { String[] appVersionDigits = appVersion.substring(1).split("\\."); - String[] allowedVersionDigits = allowedAppVersion.substring(1).split("\\."); + String[] allowedVersionDigits = ALLOWED_VERSION_TO_STOP_USING_APP_OWNER_FOR_TOKEN_IDENTIFICATION.substring(1) + .split("\\."); for (int i = 0; i < appVersionDigits.length; i++) { if (appVersionDigits[i].equals(allowedVersionDigits[i])) { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/TokenValidationHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/TokenValidationHandler.java index fabb785dbba..1915185e210 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/TokenValidationHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/TokenValidationHandler.java @@ -27,7 +27,6 @@ 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; -import org.wso2.carbon.identity.application.mgt.ApplicationConstants; import org.wso2.carbon.identity.central.log.mgt.utils.LogConstants; import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; @@ -579,8 +578,7 @@ private OAuth2IntrospectionResponseDTO validateAccessToken(OAuth2TokenValidation String consumerKey = accessTokenDO.getConsumerKey(); ServiceProvider serviceProvider = OAuth2Util.getServiceProvider(consumerKey, appResidentTenantDomain); boolean removeUsernameFromAppTokenEnabled = OAuth2Util - .isAppVersionAllowed(serviceProvider.getApplicationVersion(), - ApplicationConstants.ApplicationVersion.APP_VERSION_V1); + .isAllowedToStopUsingAppOwnerForTokenIdentification(serviceProvider.getApplicationVersion()); boolean isAppTokenType = StringUtils.equals(OAuthConstants.UserType.APPLICATION, tokenType); // should be in seconds 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 2f2eab51d09..04285362668 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,14 +18,9 @@ package org.wso2.carbon.identity.openidconnect.util; -import org.wso2.carbon.identity.application.common.model.ServiceProvider; -import org.wso2.carbon.identity.application.mgt.ApplicationConstants; -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; @@ -35,21 +30,11 @@ */ public class ClaimHandlerUtil { - /** - * 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 { + public static CustomClaimsCallbackHandler getClaimsCallbackHandler(OAuthAppDO oAuthAppDO) { // 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. - int appTenantId = IdentityTenantUtil.getLoginTenantId(); - String tenantDomain = IdentityTenantUtil.getTenantDomain(appTenantId); - if (isAccessTokenClaimsSeparationFeatureEnabled() && - isAccessTokenClaimsSeparationEnabledForApp(oAuthAppDO, tenantDomain)) { + if (isAccessTokenClaimsSeparationFeatureEnabled() && oAuthAppDO.isAccessTokenClaimsSeparationEnabled()) { return OAuthServerConfiguration.getInstance().getJWTAccessTokenOIDCClaimsHandler(); } return OAuthServerConfiguration.getInstance().getOpenIDConnectCustomClaimsCallbackHandler(); @@ -59,13 +44,4 @@ 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(); - - return OAuth2Util.isAppVersionAllowed(appVersion, ApplicationConstants.ApplicationVersion.APP_VERSION_V2); - } } diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImplTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImplTest.java index b1dedc37d12..643bad39f0c 100755 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImplTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImplTest.java @@ -35,7 +35,6 @@ import org.testng.annotations.Test; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.common.model.ServiceProvider; import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; import org.wso2.carbon.identity.core.internal.IdentityCoreServiceComponent; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; @@ -43,7 +42,6 @@ import org.wso2.carbon.identity.oauth.common.OAuth2ErrorCodes; import org.wso2.carbon.identity.oauth.common.OAuthConstants; import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthClientException; -import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; import org.wso2.carbon.identity.oauth.dao.OAuthAppDAO; import org.wso2.carbon.identity.oauth.dao.OAuthAppDO; import org.wso2.carbon.identity.oauth.dto.OAuthAppRevocationRequestDTO; @@ -58,7 +56,6 @@ import org.wso2.carbon.identity.oauth2.dao.TokenManagementDAOImpl; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; import org.wso2.carbon.identity.oauth2.model.AccessTokenDO; -import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.user.api.RealmConfiguration; import org.wso2.carbon.user.api.Tenant; import org.wso2.carbon.user.api.UserRealm; @@ -90,13 +87,11 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import static org.wso2.carbon.identity.oauth.common.OAuthConstants.ENABLE_CLAIMS_SEPARATION_FOR_ACCESS_TOKEN; public class OAuthAdminServiceImplTest { @@ -125,10 +120,9 @@ public class OAuthAdminServiceImplTest { AbstractUserStoreManager mockAbstractUserStoreManager; @Mock OAuthComponentServiceHolder mockOAuthComponentServiceHolder; + @Mock - ServiceProvider mockServiceProvider; - @Mock - OAuthServerConfiguration mockOAuthServerConfiguration; + ObjectMapper objectMapper; private MockedStatic identityTenantUtil; @@ -341,65 +335,23 @@ public void testGetAllOAuthApplicationDataException() throws Exception { } } - @DataProvider(name = "setAccessTokenClaims") - public Object[][] getOAuthApplicationData() { - - return new Object[][] { - { "v0.0.0", true }, - { "v1.0.0", true }, - { "v2.0.0", true }, - { "v0.0.0", false }, - { "v1.0.0", false }, - { "v2.0.0", false } - }; - } - - @Test(dataProvider = "setAccessTokenClaims") - public void testGetOAuthApplicationData(String appVersion, boolean claimSeparationFeatureEnabled) throws Exception { - - try (MockedStatic oAuthServerConfigurationMockedStatic = mockStatic( - OAuthServerConfiguration.class);) { - // Mock and initialize the OAuthServerConfiguration. - mockOAuthServerConfiguration = mock(OAuthServerConfiguration.class); - oAuthServerConfigurationMockedStatic.when(OAuthServerConfiguration::getInstance) - .thenReturn(mockOAuthServerConfiguration); - lenient().when(mockOAuthServerConfiguration.getTimeStampSkewInSeconds()).thenReturn(300L); - - try (MockedStatic identityUtil = mockStatic(IdentityUtil.class); - MockedStatic oAuth2Util = mockStatic(OAuth2Util.class);) { - - String consumerKey = "some-consumer-key"; - Mockito.when(tenantManager.getTenantId(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) - .thenReturn(MultitenantConstants.SUPER_TENANT_ID); - - identityUtil.when(() -> IdentityUtil.getProperty(ENABLE_CLAIMS_SEPARATION_FOR_ACCESS_TOKEN)) - .thenReturn(claimSeparationFeatureEnabled ? "true" : "false"); - - mockServiceProvider = mock(ServiceProvider.class); - oAuth2Util.when(() -> OAuth2Util.getServiceProvider(anyString(), anyString())) - .thenReturn(mockServiceProvider); - when(mockServiceProvider.getApplicationVersion()).thenReturn(appVersion); - - OAuthAppDO app = buildDummyOAuthAppDO("some-user-name"); - try (MockedConstruction mockedConstruction = Mockito.mockConstruction(OAuthAppDAO.class, - (mock, context) -> { - when(mock.getAppInformation(consumerKey, MultitenantConstants.SUPER_TENANT_ID)) - .thenReturn(app); - })) { + @Test + public void testGetOAuthApplicationData() throws Exception { - ApplicationManagementService appMgtService = mock(ApplicationManagementService.class); - OAuth2ServiceComponentHolder.setApplicationMgtService(appMgtService); - when(appMgtService.getServiceProvider(consumerKey, MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) - .thenReturn(mockServiceProvider); + String consumerKey = "some-consumer-key"; + Mockito.when(tenantManager.getTenantId(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) + .thenReturn(MultitenantConstants.SUPER_TENANT_ID); - OAuthAdminServiceImpl oAuthAdminServiceImpl = new OAuthAdminServiceImpl(); - OAuthConsumerAppDTO oAuthConsumerApp = oAuthAdminServiceImpl.getOAuthApplicationData(consumerKey, - MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); - oAuthConsumerApp.setUsername(app.getUser().toString()); + OAuthAppDO app = buildDummyOAuthAppDO("some-user-name"); + try (MockedConstruction mockedConstruction = Mockito.mockConstruction(OAuthAppDAO.class, + (mock, context) -> { + when(mock.getAppInformation(consumerKey, MultitenantConstants.SUPER_TENANT_ID)).thenReturn(app); + })) { - assertAllAttributesOfConsumerAppDTO(oAuthConsumerApp, app); - } - } + OAuthAdminServiceImpl oAuthAdminServiceImpl = new OAuthAdminServiceImpl(); + OAuthConsumerAppDTO oAuthConsumerApp = oAuthAdminServiceImpl.getOAuthApplicationData(consumerKey, + MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + assertAllAttributesOfConsumerAppDTO(oAuthConsumerApp, app); } } @@ -554,16 +506,10 @@ public Object[][] getUpdateConsumerAppTestData() { return new Object[][]{ // Logged In user , App Owner in Request , App Owner in request exists, Excepted App Owner after update - {"admin@carbon.super", "H2/new-app-owner@carbon.super", false, "original-app-owner@wso2.com", - true, "v2.0.0"}, - {"admin@carbon.super", "H2/new-app-owner@carbon.super", true, "H2/new-app-owner@carbon.super", - true, "v2.0.0"}, - {"admin@wso2.com", "H2/new-app-owner@wso2.com", false, "original-app-owner@wso2.com", - true, "v2.0.0"}, - {"admin@wso2.com", "H2/new-app-owner@wso2.com", true, "H2/new-app-owner@wso2.com", - true, "v2.0.0"}, - {"admin@carbon.super", "H2/new-app-owner@carbon.super", false, "original-app-owner@wso2.com", - false, "v2.0.0"}, + {"admin@carbon.super", "H2/new-app-owner@carbon.super", false, "original-app-owner@wso2.com"}, + {"admin@carbon.super", "H2/new-app-owner@carbon.super", true, "H2/new-app-owner@carbon.super"}, + {"admin@wso2.com", "H2/new-app-owner@wso2.com", false, "original-app-owner@wso2.com"}, + {"admin@wso2.com", "H2/new-app-owner@wso2.com", true, "H2/new-app-owner@wso2.com"} }; } @@ -586,108 +532,80 @@ private AuthenticatedUser buildUser(String fullQualifiedUsername) { public void testUpdateConsumerApplication(String loggedInUsername, String appOwnerInRequest, boolean appOwnerInRequestExists, - String expectedAppOwnerAfterUpdate, - boolean claimSeparationFeatureEnabled, String appVersion) - throws Exception { + String expectedAppOwnerAfterUpdate) throws Exception { - try (MockedStatic oAuthServerConfigurationMockedStatic = mockStatic( - OAuthServerConfiguration.class);) { - // Mock and initialize the OAuthServerConfiguration. - mockOAuthServerConfiguration = mock(OAuthServerConfiguration.class); - oAuthServerConfigurationMockedStatic.when(OAuthServerConfiguration::getInstance) - .thenReturn(mockOAuthServerConfiguration); - lenient().when(mockOAuthServerConfiguration.getTimeStampSkewInSeconds()).thenReturn(300L); - - try (MockedStatic identityUtil = mockStatic(IdentityUtil.class); - MockedStatic oAuthComponentServiceHolder = - mockStatic(OAuthComponentServiceHolder.class); - MockedStatic oAuth2Util = mockStatic(OAuth2Util.class)) { - - identityUtil.when(() -> IdentityUtil.getProperty(ENABLE_CLAIMS_SEPARATION_FOR_ACCESS_TOKEN)) - .thenReturn(claimSeparationFeatureEnabled ? "true" : "false"); - - oAuth2Util.when(() -> OAuth2Util.getServiceProvider(anyString(), anyString())) - .thenReturn(mockServiceProvider); - when(mockServiceProvider.getApplicationVersion()).thenReturn(appVersion); - - AuthenticatedUser loggedInUser = buildUser(loggedInUsername); - identityUtil.when(() -> IdentityUtil.isUserStoreCaseSensitive(anyString(), anyInt())).thenReturn(true); - identityUtil.when(() -> IdentityUtil.addDomainToName(anyString(), anyString())).thenCallRealMethod(); - - PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(loggedInUser.getTenantDomain()); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId( - IdentityTenantUtil.getTenantId(loggedInUser.getTenantDomain())); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(loggedInUser.getUserName()); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setUserRealm(userRealm); - - AuthenticatedUser appOwner = buildUser(appOwnerInRequest); - String tenantAwareUsernameOfAppOwner = - MultitenantUtils.getTenantAwareUsername(appOwner.toFullQualifiedUsername()); - - when(userStoreManager.isExistingUser(tenantAwareUsernameOfAppOwner)).thenReturn( - appOwnerInRequestExists); - - String consumerKey = UUID.randomUUID().toString(); - OAuthAppDO app = buildDummyOAuthAppDO("original-app-owner"); - AuthenticatedUser originalOwner = app.getAppOwner(); - - try (MockedConstruction mockedConstruction = Mockito.mockConstruction(OAuthAppDAO.class, - (mock, context) -> { - when(mock.getAppInformation(consumerKey, - IdentityTenantUtil.getTenantId(loggedInUser.getTenantDomain()))) - .thenReturn(app); - })) { - - ApplicationManagementService appMgtService = mock(ApplicationManagementService.class); - OAuth2ServiceComponentHolder.setApplicationMgtService(appMgtService); - when(appMgtService.getServiceProvider(consumerKey, MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) - .thenReturn(mockServiceProvider); - - OAuthAdminServiceImpl oAuthAdminServiceImpl = new OAuthAdminServiceImpl(); - OAuthConsumerAppDTO consumerAppDTO = new OAuthConsumerAppDTO(); - consumerAppDTO.setApplicationName("new-application-name"); - consumerAppDTO.setCallbackUrl("http://new-call-back-url.com"); - consumerAppDTO.setOauthConsumerKey(consumerKey); - consumerAppDTO.setOauthConsumerSecret("some-consumer-secret"); - consumerAppDTO.setOAuthVersion("new-oauth-version"); - consumerAppDTO.setUsername(appOwner.toFullQualifiedUsername()); - - mockOAuthComponentServiceHolder(oAuthComponentServiceHolder); - - String tenantDomain = MultitenantUtils.getTenantDomain(appOwnerInRequest); - String userStoreDomain = UserCoreUtil.extractDomainFromName(appOwnerInRequest); - String domainFreeName = UserCoreUtil.removeDomainFromName(appOwnerInRequest); - String username = MultitenantUtils.getTenantAwareUsername(domainFreeName); - - org.wso2.carbon.user.core.common.User user = new org.wso2.carbon.user.core.common.User(); - user.setUsername(username); - user.setTenantDomain(tenantDomain); - user.setUserStoreDomain(userStoreDomain); - Mockito.when(mockAbstractUserStoreManager.getUser(any(), anyString())).thenReturn(user); - Mockito.when(mockAbstractUserStoreManager.isExistingUser(anyString())) - .thenReturn(appOwnerInRequestExists); - - oAuthAdminServiceImpl.updateConsumerApplication(consumerAppDTO); - OAuthConsumerAppDTO updatedOAuthConsumerApp = - oAuthAdminServiceImpl.getOAuthApplicationData(consumerKey, - tenantDomain); - Assert.assertEquals(updatedOAuthConsumerApp.getApplicationName(), - consumerAppDTO.getApplicationName(), - "Updated Application name should be same as the application name in consumerAppDTO " + - "data object."); - Assert.assertEquals(updatedOAuthConsumerApp.getCallbackUrl(), consumerAppDTO.getCallbackUrl(), - "Updated Application callbackUrl should be same as the callbackUrl in consumerAppDTO " + - "data object."); - - if (appOwnerInRequestExists) { - // Application update should change the app owner if the app owner sent in the request is a - // valid user. - Assert.assertNotEquals(updatedOAuthConsumerApp.getUsername(), - originalOwner.toFullQualifiedUsername()); - } - Assert.assertEquals(updatedOAuthConsumerApp.getUsername(), expectedAppOwnerAfterUpdate); + try (MockedStatic identityUtil = mockStatic(IdentityUtil.class); + MockedStatic oAuthComponentServiceHolder = + mockStatic(OAuthComponentServiceHolder.class);) { + + AuthenticatedUser loggedInUser = buildUser(loggedInUsername); + identityUtil.when(() -> IdentityUtil.isUserStoreCaseSensitive(anyString(), anyInt())).thenReturn(true); + identityUtil.when(() -> IdentityUtil.addDomainToName(anyString(), anyString())).thenCallRealMethod(); + + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(loggedInUser.getTenantDomain()); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId( + IdentityTenantUtil.getTenantId(loggedInUser.getTenantDomain())); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(loggedInUser.getUserName()); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setUserRealm(userRealm); + + AuthenticatedUser appOwner = buildUser(appOwnerInRequest); + String tenantAwareUsernameOfAppOwner = + MultitenantUtils.getTenantAwareUsername(appOwner.toFullQualifiedUsername()); + + when(userStoreManager.isExistingUser(tenantAwareUsernameOfAppOwner)).thenReturn(appOwnerInRequestExists); + + String consumerKey = UUID.randomUUID().toString(); + OAuthAppDO app = buildDummyOAuthAppDO("original-app-owner"); + AuthenticatedUser originalOwner = app.getAppOwner(); + + try (MockedConstruction mockedConstruction = Mockito.mockConstruction(OAuthAppDAO.class, + (mock, context) -> { + when(mock.getAppInformation(consumerKey, + IdentityTenantUtil.getTenantId(loggedInUser.getTenantDomain()))) + .thenReturn(app); + })) { + + OAuthAdminServiceImpl oAuthAdminServiceImpl = new OAuthAdminServiceImpl(); + OAuthConsumerAppDTO consumerAppDTO = new OAuthConsumerAppDTO(); + consumerAppDTO.setApplicationName("new-application-name"); + consumerAppDTO.setCallbackUrl("http://new-call-back-url.com"); + consumerAppDTO.setOauthConsumerKey(consumerKey); + consumerAppDTO.setOauthConsumerSecret("some-consumer-secret"); + consumerAppDTO.setOAuthVersion("new-oauth-version"); + consumerAppDTO.setUsername(appOwner.toFullQualifiedUsername()); + + mockOAuthComponentServiceHolder(oAuthComponentServiceHolder); + + String tenantDomain = MultitenantUtils.getTenantDomain(appOwnerInRequest); + String userStoreDomain = UserCoreUtil.extractDomainFromName(appOwnerInRequest); + String domainFreeName = UserCoreUtil.removeDomainFromName(appOwnerInRequest); + String username = MultitenantUtils.getTenantAwareUsername(domainFreeName); + + org.wso2.carbon.user.core.common.User user = new org.wso2.carbon.user.core.common.User(); + user.setUsername(username); + user.setTenantDomain(tenantDomain); + user.setUserStoreDomain(userStoreDomain); + Mockito.when(mockAbstractUserStoreManager.getUser(any(), anyString())).thenReturn(user); + Mockito.when(mockAbstractUserStoreManager.isExistingUser(anyString())) + .thenReturn(appOwnerInRequestExists); + + oAuthAdminServiceImpl.updateConsumerApplication(consumerAppDTO); + OAuthConsumerAppDTO updatedOAuthConsumerApp = oAuthAdminServiceImpl.getOAuthApplicationData(consumerKey, + tenantDomain); + Assert.assertEquals(updatedOAuthConsumerApp.getApplicationName(), consumerAppDTO.getApplicationName(), + "Updated Application name should be same as the application name in consumerAppDTO " + + "data object."); + Assert.assertEquals(updatedOAuthConsumerApp.getCallbackUrl(), consumerAppDTO.getCallbackUrl(), + "Updated Application callbackUrl should be same as the callbackUrl in consumerAppDTO " + + "data object."); + + if (appOwnerInRequestExists) { + // Application update should change the app owner if the app owner sent in the request is a + // valid user. + Assert.assertNotEquals(updatedOAuthConsumerApp.getUsername(), + originalOwner.toFullQualifiedUsername()); } + Assert.assertEquals(updatedOAuthConsumerApp.getUsername(), expectedAppOwnerAfterUpdate); } } } diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java new file mode 100644 index 00000000000..36eb893b528 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/cache/AuthorizationGrantCacheTest.java @@ -0,0 +1,150 @@ +package org.wso2.carbon.identity.oauth.cache; + +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.JWTParser; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.MockitoAnnotations; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.wso2.carbon.identity.application.authentication.framework.store.SessionDataStore; +import org.wso2.carbon.identity.base.IdentityConstants; +import org.wso2.carbon.identity.core.util.IdentityUtil; +import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.dao.AccessTokenDAO; +import org.wso2.carbon.identity.oauth2.dao.AuthorizationCodeDAO; +import org.wso2.carbon.identity.oauth2.dao.OAuthTokenPersistenceFactory; +import org.wso2.carbon.identity.testutil.IdentityBaseTest; + +import java.text.ParseException; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class AuthorizationGrantCacheTest extends IdentityBaseTest { + + @Mock + private AccessTokenDAO accessTokenDAO; + + private AuthorizationGrantCache cache; + + @Mock + private OAuthTokenPersistenceFactory mockedOAuthTokenPersistenceFactory; + + @Mock + private AuthorizationCodeDAO authorizationCodeDAO; + + @Mock + private SessionDataStore sessionDataStore; + + private static final String AUTHORIZATION_GRANT_CACHE_NAME = "AuthorizationGrantCache"; + + @BeforeMethod + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + cache = AuthorizationGrantCache.getInstance(); + } + + @Test(dataProvider = "replaceFromTokenIdDataProvider") + public void testReplaceFromTokenId(String accessToken, String jwtId, String tokenId, boolean isJwtToken, + boolean isInvalidJWTToken, boolean isFailedTokenRetrieval) throws Exception { + + try (MockedStatic mockedFactory = mockStatic(OAuthTokenPersistenceFactory.class); + MockedStatic mockedJwtParser = mockStatic(JWTParser.class); + MockedStatic mockedSessionDataStore = mockStatic(SessionDataStore.class); + MockedStatic mockedIdentityUtil = mockStatic(IdentityUtil.class)) { + + mockedFactory.when(OAuthTokenPersistenceFactory::getInstance).thenReturn( + mockedOAuthTokenPersistenceFactory); + + when(mockedOAuthTokenPersistenceFactory.getAccessTokenDAO()).thenReturn(accessTokenDAO); + + if (isJwtToken) { + JWT jwtMock = mock(JWT.class); + JWTClaimsSet claimsSetMock = mock(JWTClaimsSet.class); + + if (isInvalidJWTToken) { + mockedIdentityUtil.when(() -> IdentityUtil.isTokenLoggable( + IdentityConstants.IdentityTokens.ACCESS_TOKEN)).thenReturn(true); + when(JWTParser.parse(accessToken)).thenThrow(new ParseException("Invalid JWT", 0)); + } else { + mockedJwtParser.when(() -> JWTParser.parse(accessToken)).thenReturn(jwtMock); + when(jwtMock.getJWTClaimsSet()).thenReturn(claimsSetMock); + when(claimsSetMock.getJWTID()).thenReturn(jwtId); + } + } + + if (isFailedTokenRetrieval) { + when(accessTokenDAO.getTokenIdByAccessToken(jwtId)).thenThrow( + new IdentityOAuth2Exception("Failed to retrieve token id by token from store")); + } else { + when(accessTokenDAO.getTokenIdByAccessToken(jwtId != null ? jwtId : accessToken)).thenReturn(tokenId); + } + + // Mock SessionDataStore static instance and return a mock session data store + mockedSessionDataStore.when(SessionDataStore::getInstance).thenReturn(sessionDataStore); + + // Mock SessionDataStore return for session data (from getFromSessionStore) + AuthorizationGrantCacheEntry mockCacheEntry = new AuthorizationGrantCacheEntry(); + mockCacheEntry.setTokenId(tokenId); + + when(sessionDataStore.getSessionData(tokenId, AUTHORIZATION_GRANT_CACHE_NAME)).thenReturn(mockCacheEntry); + + AuthorizationGrantCacheKey key = new AuthorizationGrantCacheKey(accessToken); + AuthorizationGrantCacheEntry result = cache.getValueFromCacheByToken(key); + + // Verify the token ID returned from the DAO is as expected + assertEquals(tokenId, result.getTokenId()); + + // Verify that the JWT token was parsed and the correct claim was retrieved if it was a JWT + if (isJwtToken && !isInvalidJWTToken) { + verify(accessTokenDAO).getTokenIdByAccessToken(jwtId); + } else { + verify(accessTokenDAO).getTokenIdByAccessToken(accessToken); + } + } + } + + @DataProvider(name = "replaceFromTokenIdDataProvider") + public Object[][] getReplaceFromTokenIdData() { + return new Object[][]{ + {"jwt.Access.Token", "jwtId", "jwtTokenId", true, false, false}, + {"nonJWTAccessToken", null, "nonJWTTokenId", false, false, false}, + {"invalid.JWT.Token", null, "invalid.JWT.Token", true, true, false}, + {"fail.Store.TokenId", "jwtId", "jwtId", true, false, true} + }; + } + + @Test + public void testGetValueFromCacheByCode() throws IdentityOAuth2Exception { + String authCode = "authCode"; + String codeId = "codeId"; + AuthorizationGrantCacheKey key = new AuthorizationGrantCacheKey(authCode); + AuthorizationGrantCacheEntry expectedEntry = new AuthorizationGrantCacheEntry(); + expectedEntry.setCodeId(codeId); + + try (MockedStatic mockedFactory = mockStatic(OAuthTokenPersistenceFactory.class); + MockedStatic mockedSessionDataStore = mockStatic(SessionDataStore.class); + MockedStatic mockedIdentityUtil = mockStatic(IdentityUtil.class)) { + + mockedSessionDataStore.when(SessionDataStore::getInstance).thenReturn(sessionDataStore); + when(sessionDataStore.getSessionData(codeId, "AuthorizationGrantCache")).thenReturn(expectedEntry); + mockedIdentityUtil.when(() -> IdentityUtil.isTokenLoggable( + IdentityConstants.IdentityTokens.AUTHORIZATION_CODE)).thenReturn(true); + + mockedFactory.when(OAuthTokenPersistenceFactory::getInstance). + thenReturn(mockedOAuthTokenPersistenceFactory); + when(mockedOAuthTokenPersistenceFactory.getAuthorizationCodeDAO()).thenReturn(authorizationCodeDAO); + when(authorizationCodeDAO.getCodeIdByAuthorizationCode(authCode)).thenReturn(codeId); + + AuthorizationGrantCacheEntry result = cache.getValueFromCacheByCode(key); + + assertEquals(expectedEntry, result); + } + } +} diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authcontext/JWTTokenGeneratorTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authcontext/JWTTokenGeneratorTest.java index 26629058e49..2ab225994c8 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authcontext/JWTTokenGeneratorTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authcontext/JWTTokenGeneratorTest.java @@ -33,7 +33,6 @@ import org.wso2.carbon.identity.common.testng.WithH2Database; import org.wso2.carbon.identity.common.testng.WithKeyStore; import org.wso2.carbon.identity.common.testng.WithRealmService; -import org.wso2.carbon.identity.core.IdentityKeyStoreResolver; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.oauth.IdentityOAuthAdminException; @@ -47,6 +46,7 @@ import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; import org.wso2.carbon.identity.oauth2.keyidprovider.DefaultKeyIDProviderImpl; import org.wso2.carbon.identity.oauth2.model.AccessTokenDO; +import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.identity.oauth2.validators.OAuth2TokenValidationMessageContext; import org.wso2.carbon.identity.testutil.ReadCertStoreSampleUtil; import org.wso2.carbon.user.core.UserCoreConstants; @@ -163,16 +163,16 @@ public void testGenerateToken() throws Exception { addSampleOauth2Application(); ClaimCache claimsLocalCache = ClaimCache.getInstance(); setPrivateField(jwtTokenGenerator, "claimsLocalCache", claimsLocalCache); - Map publicCerts = new ConcurrentHashMap<>(); - publicCerts.put("-1234", ReadCertStoreSampleUtil.createKeyStore(getClass()) + Map publicCerts = new ConcurrentHashMap<>(); + publicCerts.put(-1234, ReadCertStoreSampleUtil.createKeyStore(getClass()) .getCertificate("wso2carbon")); OAuthComponentServiceHolder.getInstance().setRealmService(realmService); when(realmService.getTenantManager()).thenReturn(tenantManager); - setFinalStatic(IdentityKeyStoreResolver.class.getDeclaredField("publicCerts"), publicCerts); - Map privateKeys = new ConcurrentHashMap<>(); - privateKeys.put("-1234", ReadCertStoreSampleUtil.createKeyStore(getClass()) + setFinalStatic(OAuth2Util.class.getDeclaredField("publicCerts"), publicCerts); + Map privateKeys = new ConcurrentHashMap<>(); + privateKeys.put(-1234, ReadCertStoreSampleUtil.createKeyStore(getClass()) .getKey("wso2carbon", "wso2carbon".toCharArray())); - setFinalStatic(IdentityKeyStoreResolver.class.getDeclaredField("privateKeys"), privateKeys); + setFinalStatic(OAuth2Util.class.getDeclaredField("privateKeys"), privateKeys); accessToken.setTokenType("Bearer"); oAuth2TokenValidationRequestDTO.setAccessToken(accessToken); diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/util/OAuth2UtilTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/util/OAuth2UtilTest.java index 8ee514e70d0..e2fb35e256e 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/util/OAuth2UtilTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/util/OAuth2UtilTest.java @@ -2838,25 +2838,6 @@ public void getSupportedTokenBindingTypes() { Assert.assertEquals(supportedTokenBindingTypes.size(), 3); } - @DataProvider(name = "isAppVersionAllowedDataProvider") - public Object[][] isAppVersionAllowedDataProvider() { - - return new Object[][]{ - {"v0.0.0", "v1.0.0", false}, - {"v1.0.0", "v1.0.0", true}, - {"v2.0.0", "v1.0.0", true}, - {"v0.0.0", "v2.0.0", false}, - {"v1.0.0", "v2.0.0", false}, - {"v2.0.0", "v2.0.0", true}, - }; - } - - @Test(dataProvider = "isAppVersionAllowedDataProvider") - public void testIsAppVersionAllowed(String appVersion, String allowedVersions, boolean expected) { - - assertEquals(OAuth2Util.isAppVersionAllowed(appVersion, allowedVersions), expected); - } - private void setPrivateField(Object object, String fieldName, Object value) throws Exception { Field field = object.getClass().getDeclaredField(fieldName); diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/DefaultIDTokenBuilderTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/DefaultIDTokenBuilderTest.java index 1b9ed2a3153..48ca3b418b4 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/DefaultIDTokenBuilderTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/DefaultIDTokenBuilderTest.java @@ -43,7 +43,6 @@ import org.wso2.carbon.identity.common.testng.WithH2Database; import org.wso2.carbon.identity.common.testng.WithKeyStore; import org.wso2.carbon.identity.common.testng.WithRealmService; -import org.wso2.carbon.identity.core.IdentityKeyStoreResolver; import org.wso2.carbon.identity.core.persistence.JDBCPersistenceManager; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; @@ -71,6 +70,7 @@ import org.wso2.carbon.identity.oauth2.test.utils.CommonTestUtils; import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; import org.wso2.carbon.identity.oauth2.token.handlers.grant.saml.SAML2BearerGrantHandlerTest; +import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.identity.openidconnect.dao.ScopeClaimMappingDAOImpl; import org.wso2.carbon.identity.openidconnect.internal.OpenIDConnectServiceComponentHolder; import org.wso2.carbon.identity.openidconnect.model.RequestedClaim; @@ -250,14 +250,14 @@ public void setUp() throws Exception { .addUser(TestConstants.USER_NAME, TestConstants.PASSWORD, new String[0], claims, TestConstants.DEFAULT_PROFILE); - Map publicCerts = new ConcurrentHashMap<>(); - publicCerts.put(String.valueOf(SUPER_TENANT_ID), ReadCertStoreSampleUtil.createKeyStore(getClass()) + Map publicCerts = new ConcurrentHashMap<>(); + publicCerts.put(SUPER_TENANT_ID, ReadCertStoreSampleUtil.createKeyStore(getClass()) .getCertificate("wso2carbon")); - setFinalStatic(IdentityKeyStoreResolver.class.getDeclaredField("publicCerts"), publicCerts); - Map privateKeys = new ConcurrentHashMap<>(); - privateKeys.put(String.valueOf(SUPER_TENANT_ID), ReadCertStoreSampleUtil.createKeyStore(getClass()) + setFinalStatic(OAuth2Util.class.getDeclaredField("publicCerts"), publicCerts); + Map privateKeys = new ConcurrentHashMap<>(); + privateKeys.put(SUPER_TENANT_ID, ReadCertStoreSampleUtil.createKeyStore(getClass()) .getKey("wso2carbon", "wso2carbon".toCharArray())); - setFinalStatic(IdentityKeyStoreResolver.class.getDeclaredField("privateKeys"), privateKeys); + setFinalStatic(OAuth2Util.class.getDeclaredField("privateKeys"), privateKeys); OpenIDConnectServiceComponentHolder.getInstance() .getOpenIDConnectClaimFilters().add(new OpenIDConnectClaimFilterImpl()); diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/util/ClaimHandlerUtilTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/util/ClaimHandlerUtilTest.java deleted file mode 100755 index 0102094ae85..00000000000 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/openidconnect/util/ClaimHandlerUtilTest.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). - * - * WSO2 LLC. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.identity.openidconnect.util; - -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.testng.MockitoTestNGListener; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Listeners; -import org.testng.annotations.Test; -import org.wso2.carbon.base.MultitenantConstants; -import org.wso2.carbon.identity.application.common.model.ServiceProvider; -import org.wso2.carbon.identity.application.mgt.ApplicationConstants; -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.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockStatic; -import static org.testng.AssertJUnit.assertEquals; -import static org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; -import static org.wso2.carbon.identity.oauth.common.OAuthConstants.ENABLE_CLAIMS_SEPARATION_FOR_ACCESS_TOKEN; - -@Listeners(MockitoTestNGListener.class) -public class ClaimHandlerUtilTest { - - @Mock - private OAuthAppDO mockOAuthAppDO; - @Mock - private CustomClaimsCallbackHandler mockJWTAccessTokenOIDCClaimsHandler; - @Mock - private CustomClaimsCallbackHandler mockOpenIDConnectCustomClaimsCallbackHandler; - @Mock - private OAuthServerConfiguration mockOAuthServerConfiguration; - - MockedStatic oAuthServerConfigurationMockedStatic; - MockedStatic identityTenantUtilMockedStatic; - MockedStatic identityUtilMockedStatic; - MockedStatic oAuth2UtilMockedStatic; - - private final String openIDConnectIDTokenCustomClaimsHandlerClassName = "SAMLAssertionClaimsCallback"; - private final String jwtAccessTokenOIDCClaimsHandlerClassName = "JWTAccessTokenOIDCClaimsHandler"; - - @BeforeMethod - public void setUp() throws Exception { - - // Mock and initialize the OAuthServerConfiguration. - oAuthServerConfigurationMockedStatic = mockStatic(OAuthServerConfiguration.class); - mockOAuthServerConfiguration = mock(OAuthServerConfiguration.class); - oAuthServerConfigurationMockedStatic.when(OAuthServerConfiguration::getInstance) - .thenReturn(mockOAuthServerConfiguration); - lenient().when(mockOAuthServerConfiguration.getTimeStampSkewInSeconds()).thenReturn(300L); - - // Initialize the static mocks. - identityTenantUtilMockedStatic = mockStatic(IdentityTenantUtil.class); - identityUtilMockedStatic = mockStatic(IdentityUtil.class); - oAuth2UtilMockedStatic = mockStatic(OAuth2Util.class); - - // Initialize the mocks. - String openIDConnectIDTokenPackageName = "org.wso2.carbon.identity.openidconnect."; - mockOAuthAppDO = mock(OAuthAppDO.class); - mockJWTAccessTokenOIDCClaimsHandler = mock(openIDConnectIDTokenPackageName - + jwtAccessTokenOIDCClaimsHandlerClassName); - mockOpenIDConnectCustomClaimsCallbackHandler = mock(openIDConnectIDTokenPackageName - + openIDConnectIDTokenCustomClaimsHandlerClassName); - - // Mock login tenant utils. - identityTenantUtilMockedStatic.when(IdentityTenantUtil::getLoginTenantId) - .thenReturn(MultitenantConstants.SUPER_TENANT_ID); - identityTenantUtilMockedStatic.when(() -> IdentityTenantUtil.getTenantDomain(-1234)) - .thenReturn(SUPER_TENANT_DOMAIN_NAME); - - // Mock the JWTAccessTokenOIDCClaimsHandler and OpenIDConnectCustomClaimsCallbackHandler. - lenient().when(mockOAuthServerConfiguration.getJWTAccessTokenOIDCClaimsHandler()) - .thenReturn(mockJWTAccessTokenOIDCClaimsHandler); - lenient().when(mockOAuthServerConfiguration.getOpenIDConnectCustomClaimsCallbackHandler()) - .thenReturn(mockOpenIDConnectCustomClaimsCallbackHandler); - } - - @AfterMethod - public void tearDown() { - - oAuthServerConfigurationMockedStatic.close(); - identityTenantUtilMockedStatic.close(); - identityUtilMockedStatic.close(); - oAuth2UtilMockedStatic.close(); - } - - @DataProvider(name = "getClaimsCallbackHandlerDataProvider") - public Object[][] getClaimsCallbackHandlerDataProvider() { - - return new Object[][] { - {true, "v0.0.0", openIDConnectIDTokenCustomClaimsHandlerClassName, false}, - {true, "v1.0.0", openIDConnectIDTokenCustomClaimsHandlerClassName, false}, - {true, "v2.0.0", jwtAccessTokenOIDCClaimsHandlerClassName, true}, - {false, "v0.0.0", openIDConnectIDTokenCustomClaimsHandlerClassName, false}, - {false, "v1.0.0", openIDConnectIDTokenCustomClaimsHandlerClassName, false}, - {false, "v2.0.0", openIDConnectIDTokenCustomClaimsHandlerClassName, true} - }; - } - - @Test(dataProvider = "getClaimsCallbackHandlerDataProvider") - public void testGetClaimsCallbackHandler(boolean isServerConfigEnabled, String appVersion, String className, - boolean isAllowed) - throws IdentityOAuth2Exception { - - // Mock the configuration for claims separation enabled on demand. - identityUtilMockedStatic.when(() -> IdentityUtil.getProperty(ENABLE_CLAIMS_SEPARATION_FOR_ACCESS_TOKEN)) - .thenReturn(isServerConfigEnabled ? "true" : "false"); - - // Mock the service provider and app version. - lenient().when(mockOAuthAppDO.getOauthConsumerKey()).thenReturn("testConsumerKey"); - ServiceProvider serviceProvider = new ServiceProvider(); - serviceProvider.setApplicationVersion(appVersion); - oAuth2UtilMockedStatic.when(() -> OAuth2Util.getServiceProvider(anyString(), anyString())) - .thenReturn(serviceProvider); - oAuth2UtilMockedStatic.when(() -> OAuth2Util.isAppVersionAllowed( - appVersion, ApplicationConstants.ApplicationVersion.APP_VERSION_V2)) - .thenReturn(isAllowed); - - CustomClaimsCallbackHandler result = ClaimHandlerUtil.getClaimsCallbackHandler(mockOAuthAppDO); - String extractedClassName = extractClassName(result.toString()); - assertEquals(extractedClassName, className); - } - - private String extractClassName(String mockClassName) { - - if (mockClassName == null || mockClassName.isEmpty()) { - return ""; - } - int lastDotIndex = mockClassName.lastIndexOf('.'); - if (lastDotIndex != -1) { - mockClassName = mockClassName.substring(lastDotIndex + 1); - } - int dollarIndex = mockClassName.indexOf('$'); - if (dollarIndex != -1) { - return mockClassName.substring(0, dollarIndex); - } - return mockClassName; - } -} diff --git a/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml b/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml old mode 100755 new mode 100644 index 91398cee77b..ba135902be7 --- a/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml +++ b/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml @@ -108,7 +108,7 @@ - + @@ -180,7 +180,7 @@ - + @@ -198,6 +198,7 @@ + diff --git a/components/org.wso2.carbon.identity.oidc.dcr/pom.xml b/components/org.wso2.carbon.identity.oidc.dcr/pom.xml index c61e6749186..968b58f365f 100644 --- a/components/org.wso2.carbon.identity.oidc.dcr/pom.xml +++ b/components/org.wso2.carbon.identity.oidc.dcr/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oidc.session/pom.xml b/components/org.wso2.carbon.identity.oidc.session/pom.xml index 9685f6e9f5c..e7d34043fa2 100644 --- a/components/org.wso2.carbon.identity.oidc.session/pom.xml +++ b/components/org.wso2.carbon.identity.oidc.session/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.webfinger/pom.xml b/components/org.wso2.carbon.identity.webfinger/pom.xml index 8b0f1994a76..a04ff06a2f8 100644 --- a/components/org.wso2.carbon.identity.webfinger/pom.xml +++ b/components/org.wso2.carbon.identity.webfinger/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/features/org.wso2.carbon.identity.oauth.common.feature/pom.xml b/features/org.wso2.carbon.identity.oauth.common.feature/pom.xml index 666b7976456..9c699d66dff 100644 --- a/features/org.wso2.carbon.identity.oauth.common.feature/pom.xml +++ b/features/org.wso2.carbon.identity.oauth.common.feature/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/features/org.wso2.carbon.identity.oauth.dcr.server.feature/pom.xml b/features/org.wso2.carbon.identity.oauth.dcr.server.feature/pom.xml index 44c3f779134..26e85815d75 100644 --- a/features/org.wso2.carbon.identity.oauth.dcr.server.feature/pom.xml +++ b/features/org.wso2.carbon.identity.oauth.dcr.server.feature/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/features/org.wso2.carbon.identity.oauth.feature/pom.xml b/features/org.wso2.carbon.identity.oauth.feature/pom.xml index 0456cdc58f0..2eb8500f4be 100644 --- a/features/org.wso2.carbon.identity.oauth.feature/pom.xml +++ b/features/org.wso2.carbon.identity.oauth.feature/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/features/org.wso2.carbon.identity.oauth.server.feature/pom.xml b/features/org.wso2.carbon.identity.oauth.server.feature/pom.xml index e0c7b1ef4ed..d2759b7ae3f 100644 --- a/features/org.wso2.carbon.identity.oauth.server.feature/pom.xml +++ b/features/org.wso2.carbon.identity.oauth.server.feature/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/features/org.wso2.carbon.identity.oauth.ui.feature/pom.xml b/features/org.wso2.carbon.identity.oauth.ui.feature/pom.xml index 3301de8fc07..010f98de7d4 100644 --- a/features/org.wso2.carbon.identity.oauth.ui.feature/pom.xml +++ b/features/org.wso2.carbon.identity.oauth.ui.feature/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index cc212203ba2..4b08c66a4e5 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ 4.0.0 org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT pom WSO2 Carbon OAuth module http://wso2.org @@ -939,7 +939,7 @@ [1.0.1, 2.0.0) - 7.5.86 + 7.5.75 [5.25.234, 8.0.0) diff --git a/service-stubs/org.wso2.carbon.claim.metadata.mgt.stub/pom.xml b/service-stubs/org.wso2.carbon.claim.metadata.mgt.stub/pom.xml index 4ef92cf1596..a03a8390167 100644 --- a/service-stubs/org.wso2.carbon.claim.metadata.mgt.stub/pom.xml +++ b/service-stubs/org.wso2.carbon.claim.metadata.mgt.stub/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT ../../pom.xml diff --git a/test-utils/org.wso2.carbon.identity.oauth.common.testng/pom.xml b/test-utils/org.wso2.carbon.identity.oauth.common.testng/pom.xml index d79872bdb8d..825f5a6cb96 100644 --- a/test-utils/org.wso2.carbon.identity.oauth.common.testng/pom.xml +++ b/test-utils/org.wso2.carbon.identity.oauth.common.testng/pom.xml @@ -23,7 +23,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.178-SNAPSHOT + 7.0.173-SNAPSHOT 4.0.0