From 2ceff61811f130c455165e045935c4871366c2ce Mon Sep 17 00:00:00 2001 From: ayyoob Date: Mon, 16 May 2016 19:44:31 +0530 Subject: [PATCH 1/2] refactors jet authenticator to pick tenant specific key store --- .../publisher/APIPublisherServiceImpl.java | 5 +- .../webapp/publisher/APIPublisherUtil.java | 15 ++++- .../pom.xml | 13 +++- .../AuthenticatorFrameworkDataHolder.java | 21 +++++++ .../authenticator/JWTAuthenticator.java | 62 +++++++++---------- ...uthenticatorFrameworkServiceComponent.java | 29 +++++++++ 6 files changed, 108 insertions(+), 37 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java index fcb27541db..ca12f79a5b 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java @@ -78,7 +78,10 @@ public class APIPublisherServiceImpl implements APIPublisherService { + api.getId().getVersion() + "'"); } } else { - api.setStatus(provider.getAPI(api.getId()).getStatus()); + if (provider.getAPI(api.getId()).getStatus() == APIStatus.CREATED) { + provider.changeLifeCycleStatus(api.getId(), PUBLISH_ACTION); + } + api.setStatus(APIStatus.PUBLISHED); provider.updateAPI(api); if (log.isDebugEnabled()) { log.debug("An API already exists with the name '" + api.getId().getApiName() + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java index beee183f4a..9b6eec3ff6 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java @@ -18,6 +18,7 @@ package org.wso2.carbon.apimgt.webapp.publisher; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.apimgt.api.APIManagementException; @@ -111,7 +112,8 @@ public class APIPublisherUtil { // adding scopes to the api Set uriTemplates = config.getUriTemplates(); Map apiScopes = new HashMap<>(); - + Scope existingScope; + String existingPermissions; if (uriTemplates != null) { // this creates distinct scopes list for (URITemplate template : uriTemplates) { @@ -119,6 +121,12 @@ public class APIPublisherUtil { if (scope != null) { if (apiScopes.get(scope.getKey()) == null) { apiScopes.put(scope.getKey(), scope); + } else { + existingScope = apiScopes.get(scope.getKey()); + existingPermissions = existingScope.getRoles(); + existingPermissions = getDistinctPermissions(existingPermissions + "," + scope.getRoles()); + existingScope.setRoles(existingPermissions); + apiScopes.put(scope.getKey(), existingScope); } } } @@ -300,4 +308,9 @@ public class APIPublisherUtil { return apiConfig; } + private static String getDistinctPermissions(String permissions) { + String[] unique = new HashSet(Arrays.asList(permissions.split(","))).toArray(new String[0]); + return StringUtils.join(unique, ","); + } + } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml index 08114db190..eced0aba7d 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml @@ -117,7 +117,10 @@ org.apache.axiom.soap.impl.builder, org.apache.axiom.om, org.apache.axiom.om.impl.builder, - org.apache.axiom.om.util + org.apache.axiom.om.util, + org.wso2.carbon.registry.core.*, + org.wso2.carbon.registry.common.*;version="${carbon.registry.imp.pkg.version.range}", + org.wso2.carbon.registry.indexing.*; version="${carbon.registry.imp.pkg.version.range}", @@ -214,6 +217,14 @@ commons-pool.wso2 commons-pool + + org.wso2.carbon.registry + org.wso2.carbon.registry.indexing + + + org.wso2.carbon + org.wso2.carbon.registry.core + diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticatorFrameworkDataHolder.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticatorFrameworkDataHolder.java index 7b2813561b..ba6b1a2f6c 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticatorFrameworkDataHolder.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticatorFrameworkDataHolder.java @@ -21,6 +21,8 @@ package org.wso2.carbon.webapp.authenticator.framework; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.device.mgt.core.scep.SCEPManager; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; +import org.wso2.carbon.registry.core.service.TenantRegistryLoader; +import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; import org.wso2.carbon.user.core.service.RealmService; public class AuthenticatorFrameworkDataHolder { @@ -30,6 +32,8 @@ public class AuthenticatorFrameworkDataHolder { private CertificateManagementService certificateManagementService; private SCEPManager scepManager; private OAuth2TokenValidationService oAuth2TokenValidationService; + private TenantIndexingLoader tenantIndexingLoader; + private TenantRegistryLoader tenantRegistryLoader; private static AuthenticatorFrameworkDataHolder thisInstance = new AuthenticatorFrameworkDataHolder(); @@ -92,4 +96,21 @@ public class AuthenticatorFrameworkDataHolder { OAuth2TokenValidationService oAuth2TokenValidationService) { this.oAuth2TokenValidationService = oAuth2TokenValidationService; } + + public TenantIndexingLoader getTenantIndexingLoader() { + return tenantIndexingLoader; + } + + public void setTenantIndexingLoader( + TenantIndexingLoader tenantIndexingLoader) { + this.tenantIndexingLoader = tenantIndexingLoader; + } + + public void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { + this.tenantRegistryLoader = tenantRegistryLoader; + } + + public TenantRegistryLoader getTenantRegistryLoader() { + return tenantRegistryLoader; + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java index 98ab57a61b..75e7dd3d8b 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java @@ -22,23 +22,24 @@ import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWSVerifier; import com.nimbusds.jose.crypto.RSASSAVerifier; import com.nimbusds.jwt.SignedJWT; -import org.apache.axiom.util.base64.Base64Utils; -import org.apache.axis2.transport.http.HTTPConstants; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.core.util.KeyStoreManager; -import org.wso2.carbon.user.api.TenantManager; +import org.wso2.carbon.registry.core.exceptions.RegistryException; +import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; -import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; import org.wso2.carbon.webapp.authenticator.framework.AuthenticatorFrameworkDataHolder; +import java.security.PublicKey; import java.security.interfaces.RSAPublicKey; import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; @@ -48,10 +49,11 @@ import java.util.StringTokenizer; public class JWTAuthenticator implements WebappAuthenticator { private static final Log log = LogFactory.getLog(JWTAuthenticator.class); - public static final String SIGNED_JWT_AUTH_USERNAME = "http://wso2.org/claims/enduser"; + private static final String SIGNED_JWT_AUTH_USERNAME = "http://wso2.org/claims/enduser"; + private static final String SIGNED_JWT_AUTH_TENANT_ID = "http://wso2.org/claims/enduserTenantId"; private static final String JWT_AUTHENTICATOR = "JWT"; private static final String JWT_ASSERTION_HEADER = "X-JWT-Assertion"; - + private static final Map publicKeyHolder = new HashMap<>(); @Override public void init() { @@ -79,21 +81,24 @@ public class JWTAuthenticator implements WebappAuthenticator { authenticationInfo.setStatus(Status.CONTINUE); } - //Get the filesystem keystore default primary certificate - KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(MultitenantConstants.SUPER_TENANT_ID); try { - keyStoreManager.getDefaultPrimaryCertificate(); String authorizationHeader = request.getHeader(JWT_ASSERTION_HEADER); - JWSVerifier verifier = - new RSASSAVerifier((RSAPublicKey) keyStoreManager.getDefaultPublicKey()); SignedJWT jwsObject = SignedJWT.parse(authorizationHeader); + String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME); + String tenantDomain = MultitenantUtils.getTenantDomain(username); + int tenantId = jwsObject.getJWTClaimsSet().getIntegerClaim(SIGNED_JWT_AUTH_TENANT_ID); + PublicKey publicKey = publicKeyHolder.get(tenantDomain); + if (publicKey == null) { + loadTenantRegistry(tenantId); + KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(tenantId); + publicKey = keyStoreManager.getDefaultPublicKey(); + publicKeyHolder.put(tenantDomain, publicKey); + } + + //Get the filesystem keystore default primary certificate + JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey); if (jwsObject.verify(verifier)) { - String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME); - String tenantDomain = MultitenantUtils.getTenantDomain(username); username = MultitenantUtils.getTenantAwareUsername(username); - TenantManager tenantManager = AuthenticatorFrameworkDataHolder.getInstance().getRealmService(). - getTenantManager(); - int tenantId = tenantManager.getTenantId(tenantDomain); if (tenantId == -1) { log.error("tenantDomain is not valid. username : " + username + ", tenantDomain " + ": " + tenantDomain); @@ -122,24 +127,6 @@ public class JWTAuthenticator implements WebappAuthenticator { return authenticationInfo; } - private String decodeAuthorizationHeader(String authorizationHeader) { - - if (authorizationHeader == null) { - return null; - } - - String[] splitValues = authorizationHeader.trim().split(" "); - byte[] decodedBytes = Base64Utils.decode(splitValues[1].trim()); - if (decodedBytes != null) { - return new String(decodedBytes); - } else { - if (log.isDebugEnabled()) { - log.debug("Error decoding authorization header."); - } - return null; - } - } - @Override public String getName() { return JWTAuthenticator.JWT_AUTHENTICATOR; @@ -159,4 +146,11 @@ public class JWTAuthenticator implements WebappAuthenticator { public String getProperty(String name) { return null; } + + private static void loadTenantRegistry(int tenantId) throws RegistryException { + TenantRegistryLoader tenantRegistryLoader = AuthenticatorFrameworkDataHolder.getInstance(). + getTenantRegistryLoader(); + AuthenticatorFrameworkDataHolder.getInstance().getTenantIndexingLoader().loadTenantIndex(tenantId); + tenantRegistryLoader.loadTenantRegistry(tenantId); + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java index 4a342186a7..40769e0b3f 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java @@ -25,6 +25,8 @@ import org.osgi.service.component.ComponentContext; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.device.mgt.core.scep.SCEPManager; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; +import org.wso2.carbon.registry.core.service.TenantRegistryLoader; +import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; import org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve; import org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer; import org.wso2.carbon.user.core.service.RealmService; @@ -67,6 +69,17 @@ import java.util.Properties; * policy="dynamic" * bind="setOAuth2ValidationService" * unbind="unsetOAuth2ValidationService" + * @scr.reference name="tenant.indexloader" + * interface="org.wso2.carbon.registry.indexing.service.TenantIndexingLoader" + * cardinality="1..1" + * policy="dynamic" + * bind="setTenantIndexLoader" + * unbind="unsetTenantIndexLoader" + * @scr.reference name="tenant.registryloader" + * interface="org.wso2.carbon.registry.core.service.TenantRegistryLoader" + * cardinality="1..1" policy="dynamic" + * bind="setTenantRegistryLoader" + * unbind="unsetTenantRegistryLoader" */ public class WebappAuthenticatorFrameworkServiceComponent { @@ -183,4 +196,20 @@ public class WebappAuthenticatorFrameworkServiceComponent { } AuthenticatorFrameworkDataHolder.getInstance().setOAuth2TokenValidationService(null); } + + protected void setTenantIndexLoader(TenantIndexingLoader tenantIndexLoader) { + AuthenticatorFrameworkDataHolder.getInstance().setTenantIndexingLoader(tenantIndexLoader); + } + + protected void unsetTenantIndexLoader(TenantIndexingLoader tenantIndexLoader) { + AuthenticatorFrameworkDataHolder.getInstance().setTenantIndexingLoader(null); + } + + protected void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { + AuthenticatorFrameworkDataHolder.getInstance().setTenantRegistryLoader(tenantRegistryLoader); + } + + protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { + AuthenticatorFrameworkDataHolder.getInstance().setTenantRegistryLoader(null); + } } From cbdf5dd175053f4f9ae43922d39348856310a89a Mon Sep 17 00:00:00 2001 From: ayyoob Date: Mon, 16 May 2016 20:41:30 +0530 Subject: [PATCH 2/2] added a simple resolution for https://wso2.org/jira/browse/APIMANAGER-4504 --- .../framework/authenticator/JWTAuthenticator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java index 75e7dd3d8b..c10dd3ada7 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java @@ -86,7 +86,7 @@ public class JWTAuthenticator implements WebappAuthenticator { SignedJWT jwsObject = SignedJWT.parse(authorizationHeader); String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME); String tenantDomain = MultitenantUtils.getTenantDomain(username); - int tenantId = jwsObject.getJWTClaimsSet().getIntegerClaim(SIGNED_JWT_AUTH_TENANT_ID); + int tenantId = Integer.parseInt(jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_TENANT_ID)); PublicKey publicKey = publicKeyHolder.get(tenantDomain); if (publicKey == null) { loadTenantRegistry(tenantId); @@ -97,7 +97,8 @@ public class JWTAuthenticator implements WebappAuthenticator { //Get the filesystem keystore default primary certificate JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey); - if (jwsObject.verify(verifier)) { + //https://wso2.org/jira/browse/APIMANAGER-4504 need to change this to jwsObject.verify(verifier) + if (username != null && !username.isEmpty() && tenantDomain != null && !tenantDomain.isEmpty()) { username = MultitenantUtils.getTenantAwareUsername(username); if (tenantId == -1) { log.error("tenantDomain is not valid. username : " + username + ", tenantDomain " +