From 740124136b72a9aa26ed23a24acaeef2d04fe538 Mon Sep 17 00:00:00 2001 From: harshanl Date: Mon, 7 Dec 2015 20:25:47 +0530 Subject: [PATCH] Refactored backend oauth authenticator component and added logic to validate OAuth token from local & remote servers. --- .../backend-oauth-authenticator/pom.xml | 23 +++- .../backend/oauth/OauthAuthenticator.java | 13 +- .../oauth/OauthAuthenticatorConstants.java | 3 +- .../OAuthAuthenticatorDataHolder.java | 49 +++++++ .../OAuthAuthenticatorServiceComponent.java | 87 +++++++++++++ .../OauthAuthenticatorServiceComponent.java | 60 --------- .../oauth/validator/OAuth2TokenValidator.java | 3 +- .../validator/OAuthValidationResponse.java | 3 +- .../validator/OAuthValidatorFactory.java | 31 ++++- .../impl/ExternalOAuthValidator.java | 20 ++- .../validator/impl/LocalOAuthValidator.java | 6 +- .../pom.xml | 7 +- .../AuthenticatorFrameworkDataHolder.java | 4 +- .../authenticator/OAuthAuthenticator.java | 40 +++--- .../oauth/OAuth2TokenValidator.java | 34 +++++ .../authenticator/oauth/OAuthConstants.java | 33 +++++ .../oauth/OAuthTokenValidationException.java | 60 +++++++++ .../oauth/OAuthValidationResponse.java | 70 ++++++++++ .../oauth/OAuthValidatorFactory.java | 71 +++++++++++ .../oauth/impl/LocalOAuthValidator.java | 74 +++++++++++ .../oauth/impl/RemoteOAuthValidator.java | 120 ++++++++++++++++++ ...uthenticatorFrameworkServiceComponent.java | 4 +- pom.xml | 2 +- 23 files changed, 693 insertions(+), 124 deletions(-) create mode 100644 components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorDataHolder.java create mode 100755 components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorServiceComponent.java delete mode 100755 components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OauthAuthenticatorServiceComponent.java create mode 100755 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuth2TokenValidator.java create mode 100644 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthConstants.java create mode 100644 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthTokenValidationException.java create mode 100755 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthValidationResponse.java create mode 100755 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthValidatorFactory.java create mode 100755 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/impl/LocalOAuthValidator.java create mode 100755 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/impl/RemoteOAuthValidator.java diff --git a/components/identity-extensions/backend-oauth-authenticator/pom.xml b/components/identity-extensions/backend-oauth-authenticator/pom.xml index cb64fb694d..0c0ccd907f 100644 --- a/components/identity-extensions/backend-oauth-authenticator/pom.xml +++ b/components/identity-extensions/backend-oauth-authenticator/pom.xml @@ -88,16 +88,29 @@ ${pom.artifactId} ${pom.artifactId} ${carbon.device.mgt.version} - Identity backend Bundle - - org.wso2.carbon.identity.authenticator.backend.oauth.internal.OauthAuthenticatorServiceComponent - + OAuth Authenticator Bundle - org.wso2.org.wso2.carbon.identity.authenticator.backend.oauth.internal + org.wso2.carbon.identity.authenticator.backend.oauth.internal + !org.wso2.carbon.identity.authenticator.backend.oauth.internal, org.wso2.carbon.identity.authenticator.backend.oauth.* + + org.wso2.carbon.identity.oauth2.*, + javax.servlet.http, + org.apache.axis2.client, + org.apache.axis2.context, + org.apache.axis2.transport.http, + org.apache.commons.httpclient, + org.apache.commons.logging, + org.apache.commons.codec.binary, + org.osgi.framework, + org.osgi.service.component, + org.wso2.carbon.core.security, + org.wso2.carbon.core.services.authentication, + org.wso2.carbon.utils.multitenancy + diff --git a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/OauthAuthenticator.java b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/OauthAuthenticator.java index beaf5c70b0..3696cd6cce 100755 --- a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/OauthAuthenticator.java +++ b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/OauthAuthenticator.java @@ -44,19 +44,8 @@ public class OauthAuthenticator implements CarbonServerAuthenticator { private OAuth2TokenValidator tokenValidator; public OauthAuthenticator() { - AuthenticatorsConfiguration authenticatorsConfiguration = AuthenticatorsConfiguration.getInstance(); - AuthenticatorsConfiguration.AuthenticatorConfig authenticatorConfig = authenticatorsConfiguration. - getAuthenticatorConfig(OauthAuthenticatorConstants.AUTHENTICATOR_NAME); - boolean isRemote; - String hostUrl; - if (authenticatorConfig != null) { - isRemote = Boolean.parseBoolean(authenticatorConfig.getParameters().get("isRemote")); - hostUrl = authenticatorConfig.getParameters().get("hostURL"); - }else{ - throw new IllegalArgumentException("Configuration parameters need to be defined in Authenticators.xml"); - } try { - tokenValidator = OAuthValidatorFactory.getValidator(isRemote, hostUrl); + tokenValidator = OAuthValidatorFactory.getValidator(); } catch (IllegalArgumentException e) { log.error("Failed to initialise Authenticator",e); } diff --git a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/OauthAuthenticatorConstants.java b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/OauthAuthenticatorConstants.java index badaf8dbed..4c7ace2e6d 100755 --- a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/OauthAuthenticatorConstants.java +++ b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/OauthAuthenticatorConstants.java @@ -19,9 +19,10 @@ package org.wso2.carbon.identity.authenticator.backend.oauth; public class OauthAuthenticatorConstants { public static final String AUTHORIZATION_HEADER_PREFIX_BEARER = "Bearer"; + public static final String AUTHORIZATION_HEADER_PREFIX_BASIC = "Basic"; public static final String BEARER_TOKEN_TYPE = "bearer"; public static final String BEARER_TOKEN_IDENTIFIER = "token"; - public static final String AUTHENTICATOR_NAME = "BackEndOAuthAuthenticator"; + public static final String AUTHENTICATOR_NAME = "OAuthAuthenticator"; public static final String SPLITING_CHARACTOR = " "; public static String OAUTH_ENDPOINT_POSTFIX = "/services/OAuth2TokenValidationService.OAuth2TokenValidationServiceHttpsSoap12Endpoint/"; diff --git a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorDataHolder.java b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorDataHolder.java new file mode 100644 index 0000000000..202568c4a5 --- /dev/null +++ b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorDataHolder.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.authenticator.backend.oauth.internal; + +import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; + +/** + * DataHolder of Backend OAuth Authenticator component. + */ +public class OAuthAuthenticatorDataHolder { + + private OAuth2TokenValidationService oAuth2TokenValidationService; + + private static OAuthAuthenticatorDataHolder thisInstance = new OAuthAuthenticatorDataHolder(); + + private OAuthAuthenticatorDataHolder() {} + + public static OAuthAuthenticatorDataHolder getInstance() { + return thisInstance; + } + + public OAuth2TokenValidationService getOAuth2TokenValidationService() { + if (oAuth2TokenValidationService == null) { + throw new IllegalStateException("OAuth2TokenValidation service is not initialized properly"); + } + return oAuth2TokenValidationService; + } + + public void setOAuth2TokenValidationService( + OAuth2TokenValidationService oAuth2TokenValidationService) { + this.oAuth2TokenValidationService = oAuth2TokenValidationService; + } +} \ No newline at end of file diff --git a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorServiceComponent.java b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorServiceComponent.java new file mode 100755 index 0000000000..cdcc9a2396 --- /dev/null +++ b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorServiceComponent.java @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2015 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. 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.authenticator.backend.oauth.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.BundleContext; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.core.services.authentication.CarbonServerAuthenticator; +import org.wso2.carbon.identity.authenticator.backend.oauth.OauthAuthenticator; +import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; + +/** + * @scr.component name="org.wso2.carbon.identity.backend.oauth.authenticator" immediate="true" + * @scr.reference name="identity.oauth2.validation.service" + * interface="org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService" + * cardinality="1..1" + * policy="dynamic" + * bind="setOAuth2ValidationService" + * unbind="unsetOAuth2ValidationService" + */ +public class OAuthAuthenticatorServiceComponent { + + private static final Log log = LogFactory.getLog(OAuthAuthenticatorServiceComponent.class); + + @SuppressWarnings("unused") + protected void activate(ComponentContext componentContext) { + if (log.isDebugEnabled()) { + log.debug("Starting Backend OAuthAuthenticator Framework Bundle"); + } + try { + /* Registering BackendOAuthAuthenticator Service */ + BundleContext bundleContext = componentContext.getBundleContext(); + OauthAuthenticator oAuthAuthenticator = new OauthAuthenticator(); + bundleContext.registerService(CarbonServerAuthenticator.class.getName(), oAuthAuthenticator, null); + } catch (Throwable e) { + log.error("Error occurred while initializing the bundle", e); + } + } + + @SuppressWarnings("unused") + protected void deactivate(ComponentContext componentContext) { + //do nothing + } + + /** + * Sets OAuth2TokenValidation Service. + * + * @param tokenValidationService An instance of OAuth2TokenValidationService. + */ + @SuppressWarnings("unused") + protected void setOAuth2ValidationService(OAuth2TokenValidationService tokenValidationService) { + if (log.isDebugEnabled()) { + log.debug("Setting OAuth2TokenValidationService Service"); + } + OAuthAuthenticatorDataHolder.getInstance().setOAuth2TokenValidationService(tokenValidationService); + } + + /** + * Unsets OAuth2TokenValidation Service. + * + * @param tokenValidationService An instance of OAuth2TokenValidationService + */ + @SuppressWarnings("unused") + protected void unsetOAuth2ValidationService(OAuth2TokenValidationService tokenValidationService) { + if (log.isDebugEnabled()) { + log.debug("Unsetting OAuth2TokenValidationService Service"); + } + OAuthAuthenticatorDataHolder.getInstance().setOAuth2TokenValidationService(null); + } +} \ No newline at end of file diff --git a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OauthAuthenticatorServiceComponent.java b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OauthAuthenticatorServiceComponent.java deleted file mode 100755 index 7076afd4a6..0000000000 --- a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OauthAuthenticatorServiceComponent.java +++ /dev/null @@ -1,60 +0,0 @@ -/* -* Copyright (c) 2015 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -* -* WSO2 Inc. 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.authenticator.backend.oauth.internal; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; -import org.wso2.carbon.core.services.authentication.CarbonServerAuthenticator; -import org.wso2.carbon.identity.authenticator.backend.oauth.OauthAuthenticator; - - - -public class OauthAuthenticatorServiceComponent implements BundleActivator { - - private ServiceRegistration pipServiceRegRef; - private static final Log log = LogFactory.getLog(OauthAuthenticatorServiceComponent - .class); - - @Override - public void start(BundleContext bundleContext) throws Exception { - log.info("Initiating"); - try { - OauthAuthenticator oauthAuthenticator = new OauthAuthenticator(); - pipServiceRegRef = bundleContext.registerService(CarbonServerAuthenticator.class.getName(), - oauthAuthenticator, null); - if (log.isDebugEnabled()) { - log.debug("OAuth Authenticator bundle is activated"); - } - } catch (Throwable e) { - log.fatal(" Error while activating OAuth authenticator ", e); - } - } - - @Override - public void stop(BundleContext bundleContext) throws Exception { - if (log.isDebugEnabled()) { - log.debug("OAuth Authenticator bundle is deactivated"); - } - pipServiceRegRef.unregister(); - } - -} diff --git a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuth2TokenValidator.java b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuth2TokenValidator.java index c0c5c8662a..1dbbd0fb68 100755 --- a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuth2TokenValidator.java +++ b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuth2TokenValidator.java @@ -20,9 +20,10 @@ package org.wso2.carbon.identity.authenticator.backend.oauth.validator; import java.rmi.RemoteException; /** - * Interface for the OAuth@TokenValidators + * Declares the contract for OAuth2TokenValidator implementations. */ public interface OAuth2TokenValidator { + /** * This method gets a string accessToken and validates it and generate the OAuth2ClientApplicationDTO * containing the validity and user details if valid. diff --git a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuthValidationResponse.java b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuthValidationResponse.java index b794a22424..8804924a4c 100755 --- a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuthValidationResponse.java +++ b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuthValidationResponse.java @@ -18,10 +18,11 @@ package org.wso2.carbon.identity.authenticator.backend.oauth.validator; /** - * This class hold the validation information which can be retrieve by both remote and in house IDPs + * This class holds the authenticated user information after the OAuth2 token is validated. */ @SuppressWarnings("unused") public class OAuthValidationResponse { + private String userName; private String tenantDomain; private boolean isValid; diff --git a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuthValidatorFactory.java b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuthValidatorFactory.java index bb88d98f7e..45e89c0223 100755 --- a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuthValidatorFactory.java +++ b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/OAuthValidatorFactory.java @@ -17,7 +17,7 @@ */ package org.wso2.carbon.identity.authenticator.backend.oauth.validator; -import org.wso2.carbon.identity.authenticator.backend.oauth.AuthenticatorException; +import org.wso2.carbon.core.security.AuthenticatorsConfiguration; import org.wso2.carbon.identity.authenticator.backend.oauth.OauthAuthenticatorConstants; import org.wso2.carbon.identity.authenticator.backend.oauth.validator.impl.ExternalOAuthValidator; import org.wso2.carbon.identity.authenticator.backend.oauth.validator.impl.LocalOAuthValidator; @@ -28,15 +28,36 @@ import org.wso2.carbon.identity.authenticator.backend.oauth.validator.impl.Local */ public class OAuthValidatorFactory { + private static final String AUTHENTICATOR_CONFIG_IS_REMOTE = "isRemote"; + private static final String AUTHENTICATOR_CONFIG_HOST_URL = "hostURL"; + private static final String AUTHENTICATOR_CONFIG_ADMIN_USERNAME = "adminUsername"; + private static final String AUTHENTICATOR_CONFIG_ADMIN_PASSWORD = "adminPassword"; + /** * The method check the configuration and provide the appropriate implementation for OAuth2TokenValidator * @return OAuth2TokenValidator */ - public static OAuth2TokenValidator getValidator(boolean isRemote, String hostURL) throws IllegalArgumentException { + public static OAuth2TokenValidator getValidator() throws IllegalArgumentException { + AuthenticatorsConfiguration authenticatorsConfiguration = AuthenticatorsConfiguration.getInstance(); + AuthenticatorsConfiguration.AuthenticatorConfig authenticatorConfig = authenticatorsConfiguration. + getAuthenticatorConfig(OauthAuthenticatorConstants.AUTHENTICATOR_NAME); + boolean isRemote; + String hostUrl; + String adminUserName; + String adminPassword; + if (authenticatorConfig != null && authenticatorConfig.getParameters() != null) { + isRemote = Boolean.parseBoolean(authenticatorConfig.getParameters().get( + AUTHENTICATOR_CONFIG_IS_REMOTE)); + hostUrl = authenticatorConfig.getParameters().get(AUTHENTICATOR_CONFIG_HOST_URL); + adminUserName = authenticatorConfig.getParameters().get(AUTHENTICATOR_CONFIG_ADMIN_USERNAME); + adminPassword = authenticatorConfig.getParameters().get(AUTHENTICATOR_CONFIG_ADMIN_PASSWORD); + }else{ + throw new IllegalArgumentException("Configuration parameters need to be defined in Authenticators.xml"); + } if (isRemote) { - if (!(hostURL == null || hostURL.trim().isEmpty())) { - hostURL = hostURL + OauthAuthenticatorConstants.OAUTH_ENDPOINT_POSTFIX; - return new ExternalOAuthValidator(hostURL); + if (!(hostUrl == null || hostUrl.trim().isEmpty())) { + hostUrl = hostUrl + OauthAuthenticatorConstants.OAUTH_ENDPOINT_POSTFIX; + return new ExternalOAuthValidator(hostUrl, adminUserName, adminPassword); } else { throw new IllegalArgumentException("Remote server name and ip both can't be empty"); } diff --git a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/impl/ExternalOAuthValidator.java b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/impl/ExternalOAuthValidator.java index 8d8a101537..05f1579fa0 100755 --- a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/impl/ExternalOAuthValidator.java +++ b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/impl/ExternalOAuthValidator.java @@ -20,6 +20,7 @@ package org.wso2.carbon.identity.authenticator.backend.oauth.validator.impl; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.httpclient.Header; import org.wso2.carbon.identity.authenticator.backend.oauth.OauthAuthenticatorConstants; import org.wso2.carbon.identity.authenticator.backend.oauth.validator.OAuth2TokenValidator; @@ -35,14 +36,18 @@ import java.util.ArrayList; import java.util.List; /** - * Handles the Authentication form external IDP servers. - * Currently only supports WSO@ IS + * Handles the Authentication form external IDP servers. Currently supports WSO2 IS only. */ public class ExternalOAuthValidator implements OAuth2TokenValidator{ - protected String hostURL ; - public ExternalOAuthValidator(String hostURL) { + private String hostURL; + private String adminUserName; + private String adminPassword; + + public ExternalOAuthValidator(String hostURL, String adminUserName, String adminPassword) { this.hostURL = hostURL; + this.adminUserName = adminUserName; + this.adminPassword = adminPassword; } /** * This method gets a string accessToken and validates it and generate the OAuth2ClientApplicationDTO @@ -65,7 +70,7 @@ public class ExternalOAuthValidator implements OAuth2TokenValidator{ List
headerList = new ArrayList<>(); Header header = new Header(); header.setName(HTTPConstants.HEADER_AUTHORIZATION); - header.setValue(OauthAuthenticatorConstants.AUTHORIZATION_HEADER_PREFIX_BEARER+ " " + token); + header.setValue(OauthAuthenticatorConstants.AUTHORIZATION_HEADER_PREFIX_BASIC + " " + getBasicAuthCredentials()); headerList.add(header); options.setProperty(org.apache.axis2.transport.http.HTTPConstants.HTTP_HEADERS, headerList); client.setOptions(options); @@ -82,4 +87,9 @@ public class ExternalOAuthValidator implements OAuth2TokenValidator{ } return new OAuthValidationResponse(userName,tenantDomain,isValid); } + + private String getBasicAuthCredentials() { + byte[] bytesEncoded = Base64.encodeBase64((adminUserName + ":" + adminPassword).getBytes()); + return new String(bytesEncoded); + } } diff --git a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/impl/LocalOAuthValidator.java b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/impl/LocalOAuthValidator.java index 2deb2b3b36..17243ed411 100755 --- a/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/impl/LocalOAuthValidator.java +++ b/components/identity-extensions/backend-oauth-authenticator/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/validator/impl/LocalOAuthValidator.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.authenticator.backend.oauth.validator.impl; import org.wso2.carbon.identity.authenticator.backend.oauth.OauthAuthenticatorConstants; +import org.wso2.carbon.identity.authenticator.backend.oauth.internal.OAuthAuthenticatorDataHolder; import org.wso2.carbon.identity.authenticator.backend.oauth.validator.OAuth2TokenValidator; import org.wso2.carbon.identity.authenticator.backend.oauth.validator.OAuthValidationResponse; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; @@ -43,9 +44,8 @@ public class LocalOAuthValidator implements OAuth2TokenValidator { accessToken.setTokenType(OauthAuthenticatorConstants.BEARER_TOKEN_TYPE); accessToken.setIdentifier(token); validationRequest.setAccessToken(accessToken); - OAuth2TokenValidationService validationService = new OAuth2TokenValidationService(); - OAuth2TokenValidationResponseDTO tokenValidationResponse = validationService. - findOAuthConsumerIfTokenIsValid(validationRequest).getAccessTokenValidationResponse(); + OAuth2TokenValidationResponseDTO tokenValidationResponse = OAuthAuthenticatorDataHolder.getInstance(). + getOAuth2TokenValidationService().findOAuthConsumerIfTokenIsValid(validationRequest).getAccessTokenValidationResponse(); boolean isValid = tokenValidationResponse.isValid(); String userName = null; String tenantDomain = null; 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 4c28efc1f5..3dad448cc6 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 @@ -100,7 +100,12 @@ org.wso2.carbon.device.mgt.core.permission.mgt, org.wso2.carbon.device.mgt.common, org.wso2.carbon.device.mgt.common.permission.mgt, - org.wso2.carbon.device.mgt.core.scep + org.wso2.carbon.device.mgt.core.scep, + org.apache.axis2, + org.apache.axis2.client, + org.apache.commons.codec.binary, + org.apache.commons.httpclient, + org.wso2.carbon.core.security 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 547cda44a5..7b2813561b 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 @@ -81,14 +81,14 @@ public class AuthenticatorFrameworkDataHolder { this.scepManager = scepManager; } - public OAuth2TokenValidationService getoAuth2TokenValidationService() { + public OAuth2TokenValidationService getOAuth2TokenValidationService() { if (oAuth2TokenValidationService == null) { throw new IllegalStateException("OAuth2TokenValidation service is not initialized properly"); } return oAuth2TokenValidationService; } - public void setoAuth2TokenValidationService( + public void setOAuth2TokenValidationService( OAuth2TokenValidationService oAuth2TokenValidationService) { this.oAuth2TokenValidationService = oAuth2TokenValidationService; } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OAuthAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OAuthAuthenticator.java index ca8eb6c700..497fa3b3e2 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OAuthAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OAuthAuthenticator.java @@ -24,12 +24,15 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.buf.MessageBytes; -import org.wso2.carbon.apimgt.core.gateway.APITokenAuthenticator; import org.wso2.carbon.identity.oauth2.dto.OAuth2TokenValidationRequestDTO; import org.wso2.carbon.identity.oauth2.dto.OAuth2TokenValidationResponseDTO; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import org.wso2.carbon.webapp.authenticator.framework.*; import org.wso2.carbon.webapp.authenticator.framework.Utils.Utils; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuth2TokenValidator; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthTokenValidationException; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthValidationResponse; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthValidatorFactory; import java.util.StringTokenizer; import java.util.regex.Matcher; @@ -88,45 +91,32 @@ public class OAuthAuthenticator implements WebappAuthenticator { authenticationInfo.setStatus(Status.CONTINUE); } else { String bearerToken = this.getBearerToken(request); - // Create a OAuth2TokenValidationRequestDTO object for validating access token - OAuth2TokenValidationRequestDTO dto = new OAuth2TokenValidationRequestDTO(); - //Set the access token info - OAuth2TokenValidationRequestDTO.OAuth2AccessToken oAuth2AccessToken = dto.new OAuth2AccessToken(); - oAuth2AccessToken.setTokenType(OAuthAuthenticator.BEARER_TOKEN_TYPE); - oAuth2AccessToken.setIdentifier(bearerToken); - dto.setAccessToken(oAuth2AccessToken); //Set the resource context param. This will be used in scope validation. - OAuth2TokenValidationRequestDTO.TokenValidationContextParam - resourceContextParam = dto.new TokenValidationContextParam(); - resourceContextParam.setKey(OAuthAuthenticator.RESOURCE_KEY); - resourceContextParam.setValue(requestUri + ":" + requestMethod); + String resource = requestUri + ":" + requestMethod; + //Get the appropriate OAuth validator from OAuthValidatorFactory. + OAuth2TokenValidator oAuth2TokenValidator = OAuthValidatorFactory.getValidator(); + OAuthValidationResponse oAuthValidationResponse = oAuth2TokenValidator.validateToken(bearerToken, resource); - OAuth2TokenValidationRequestDTO.TokenValidationContextParam[] - tokenValidationContextParams = - new OAuth2TokenValidationRequestDTO.TokenValidationContextParam[1]; - tokenValidationContextParams[0] = resourceContextParam; - dto.setContext(tokenValidationContextParams); - - OAuth2TokenValidationResponseDTO oAuth2TokenValidationResponseDTO = - AuthenticatorFrameworkDataHolder.getInstance().getoAuth2TokenValidationService().validate(dto); - if (oAuth2TokenValidationResponseDTO.isValid()) { - String username = oAuth2TokenValidationResponseDTO.getAuthorizedUser(); + if (oAuthValidationResponse.isValid()) { + String username = oAuthValidationResponse.getUserName(); //Remove the userstore domain from username /*if (username.contains("/")) { username = username.substring(username.indexOf('/') + 1); }*/ authenticationInfo.setUsername(username); - authenticationInfo.setTenantDomain(MultitenantUtils.getTenantDomain(username)); + authenticationInfo.setTenantDomain(oAuthValidationResponse.getTenantDomain()); authenticationInfo.setTenantId(Utils.getTenantIdOFUser(username)); - if (oAuth2TokenValidationResponseDTO.isValid()) { + if (oAuthValidationResponse.isValid()) { authenticationInfo.setStatus(Status.CONTINUE); } } else { - authenticationInfo.setMessage(oAuth2TokenValidationResponseDTO.getErrorMsg()); + authenticationInfo.setMessage(oAuthValidationResponse.getErrorMsg()); } } } catch (AuthenticationException e) { log.error("Failed to authenticate the incoming request", e); + } catch (OAuthTokenValidationException e) { + log.error("Failed to authenticate the incoming request due to oauth token validation error.", e); } return authenticationInfo; } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuth2TokenValidator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuth2TokenValidator.java new file mode 100755 index 0000000000..50ef34081c --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuth2TokenValidator.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.webapp.authenticator.framework.authenticator.oauth; + +/** + * Declares the contract for OAuth2TokenValidator implementations. + */ +public interface OAuth2TokenValidator { + + /** + * This method gets a string accessToken and validates it and generate the OAuthValidationResponse + * containing the validity and user details if valid. + * + * @param accessToken which need to be validated. + * @param resource which need to be validated. + * @return OAuthValidationResponse with the validated results. + */ + OAuthValidationResponse validateToken(String accessToken, String resource) throws OAuthTokenValidationException; +} diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthConstants.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthConstants.java new file mode 100644 index 0000000000..0642f0e8e1 --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthConstants.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.webapp.authenticator.framework.authenticator.oauth; + +/** + * Defines constants to be used inside oauth validators. + */ +public class OAuthConstants { + + public static final String AUTHORIZATION_HEADER_PREFIX_BEARER = "Bearer"; + public static final String AUTHORIZATION_HEADER_PREFIX_BASIC = "Basic"; + public static final String BEARER_TOKEN_TYPE = "bearer"; + public static final String BEARER_TOKEN_IDENTIFIER = "token"; + public static final String AUTHENTICATOR_NAME = "OAuthAuthenticator"; + public static final String RESOURCE_KEY = "resource"; + +} diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthTokenValidationException.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthTokenValidationException.java new file mode 100644 index 0000000000..9cab2c5db7 --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthTokenValidationException.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.webapp.authenticator.framework.authenticator.oauth; + +/** + * Custom exception to be thrown inside OAuthTokenValidation related functionality. + */ +public class OAuthTokenValidationException extends Exception { + + private static final long serialVersionUID = -3151279311929070297L; + + private String errorMessage; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public OAuthTokenValidationException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public OAuthTokenValidationException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public OAuthTokenValidationException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public OAuthTokenValidationException() { + super(); + } + + public OAuthTokenValidationException(Throwable cause) { + super(cause); + } +} diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthValidationResponse.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthValidationResponse.java new file mode 100755 index 0000000000..d78b89295a --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthValidationResponse.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.webapp.authenticator.framework.authenticator.oauth; + +/** + * This class holds the authenticated user information after the OAuth2 token is validated. + */ +@SuppressWarnings("unused") +public class OAuthValidationResponse { + + private String userName; + private String tenantDomain; + private boolean isValid; + private String errorMsg; + + public OAuthValidationResponse() {} + + public OAuthValidationResponse(String userName, String tenantDomain, boolean isValid) { + this.userName = userName; + this.tenantDomain = tenantDomain; + this.isValid = isValid; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getTenantDomain() { + return tenantDomain; + } + + public void setTenantDomain(String tenantDomain) { + this.tenantDomain = tenantDomain; + } + + public boolean isValid() { + return isValid; + } + + public void setIsValid(boolean isValid) { + this.isValid = isValid; + } + + public String getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) { + this.errorMsg = errorMsg; + } +} \ No newline at end of file diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthValidatorFactory.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthValidatorFactory.java new file mode 100755 index 0000000000..44fefdf9bc --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/OAuthValidatorFactory.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.webapp.authenticator.framework.authenticator.oauth; + +import org.wso2.carbon.core.security.AuthenticatorsConfiguration; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.impl.RemoteOAuthValidator; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.impl.LocalOAuthValidator; + +/** + * The class validate the configurations and provide the most suitable implementation according to the configuration. + * Factory class for OAuthValidator. + */ +public class OAuthValidatorFactory { + + private static final String AUTHENTICATOR_CONFIG_IS_REMOTE = "isRemote"; + private static final String AUTHENTICATOR_CONFIG_HOST_URL = "hostURL"; + private static final String AUTHENTICATOR_CONFIG_ADMIN_USERNAME = "adminUsername"; + private static final String AUTHENTICATOR_CONFIG_ADMIN_PASSWORD = "adminPassword"; + private static final String AUTHENTICATOR_CONFIG_OAUTH_AUTHENTICATOR_NAME = "OAuthAuthenticator"; + private static String OAUTH_ENDPOINT_POSTFIX = + "/services/OAuth2TokenValidationService.OAuth2TokenValidationServiceHttpsSoap12Endpoint/"; + + /** + * This factory method checks the authenticators.xml configuration file and provides an appropriate implementation + * of OAuth2TokenValidator. + * @return OAuth2TokenValidator + */ + public static OAuth2TokenValidator getValidator() throws IllegalArgumentException { + AuthenticatorsConfiguration authenticatorsConfiguration = AuthenticatorsConfiguration.getInstance(); + AuthenticatorsConfiguration.AuthenticatorConfig authenticatorConfig = authenticatorsConfiguration. + getAuthenticatorConfig(AUTHENTICATOR_CONFIG_OAUTH_AUTHENTICATOR_NAME); + boolean isRemote; + String hostUrl; + String adminUserName; + String adminPassword; + if (authenticatorConfig != null && authenticatorConfig.getParameters() != null) { + isRemote = Boolean.parseBoolean(authenticatorConfig.getParameters().get( + AUTHENTICATOR_CONFIG_IS_REMOTE)); + hostUrl = authenticatorConfig.getParameters().get(AUTHENTICATOR_CONFIG_HOST_URL); + adminUserName = authenticatorConfig.getParameters().get(AUTHENTICATOR_CONFIG_ADMIN_USERNAME); + adminPassword = authenticatorConfig.getParameters().get(AUTHENTICATOR_CONFIG_ADMIN_PASSWORD); + }else{ + throw new IllegalArgumentException("OAuth Authenticator configuration parameters need to be defined in " + + "Authenticators.xml."); + } + if (isRemote) { + if (!(hostUrl == null || hostUrl.trim().isEmpty())) { + hostUrl = hostUrl + OAUTH_ENDPOINT_POSTFIX; + return new RemoteOAuthValidator(hostUrl, adminUserName, adminPassword); + } else { + throw new IllegalArgumentException("Remote server host can't be empty in authenticators.xml."); + } + } + return new LocalOAuthValidator(); + } +} diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/impl/LocalOAuthValidator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/impl/LocalOAuthValidator.java new file mode 100755 index 0000000000..352d8d8f62 --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/impl/LocalOAuthValidator.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.webapp.authenticator.framework.authenticator.oauth.impl; + +import org.wso2.carbon.identity.oauth2.dto.OAuth2TokenValidationRequestDTO; +import org.wso2.carbon.identity.oauth2.dto.OAuth2TokenValidationResponseDTO; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import org.wso2.carbon.webapp.authenticator.framework.AuthenticatorFrameworkDataHolder; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuth2TokenValidator; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthConstants; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthTokenValidationException; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthValidationResponse; + +/** + * Handles the OAuth2 token validation from the same server using OSGi services. + */ +public class LocalOAuthValidator implements OAuth2TokenValidator { + + @Override + public OAuthValidationResponse validateToken(String accessToken, String resource) + throws OAuthTokenValidationException { + OAuth2TokenValidationRequestDTO validationRequest = new OAuth2TokenValidationRequestDTO(); + OAuth2TokenValidationRequestDTO.OAuth2AccessToken oauthToken = + validationRequest.new OAuth2AccessToken(); + oauthToken.setTokenType(OAuthConstants.BEARER_TOKEN_TYPE); + oauthToken.setIdentifier(accessToken); + validationRequest.setAccessToken(oauthToken); + + //Set the resource context param. This will be used in scope validation. + OAuth2TokenValidationRequestDTO.TokenValidationContextParam + resourceContextParam = validationRequest.new TokenValidationContextParam(); + resourceContextParam.setKey(OAuthConstants.RESOURCE_KEY); + resourceContextParam.setValue(resource); + + OAuth2TokenValidationRequestDTO.TokenValidationContextParam[] + tokenValidationContextParams = + new OAuth2TokenValidationRequestDTO.TokenValidationContextParam[1]; + tokenValidationContextParams[0] = resourceContextParam; + validationRequest.setContext(tokenValidationContextParams); + + OAuth2TokenValidationResponseDTO tokenValidationResponse = AuthenticatorFrameworkDataHolder.getInstance(). + getOAuth2TokenValidationService().findOAuthConsumerIfTokenIsValid( + validationRequest).getAccessTokenValidationResponse(); + boolean isValid = tokenValidationResponse.isValid(); + String userName; + String tenantDomain; + if (isValid) { + userName = MultitenantUtils.getTenantAwareUsername( + tokenValidationResponse.getAuthorizedUser()); + tenantDomain = + MultitenantUtils.getTenantDomain(tokenValidationResponse.getAuthorizedUser()); + } else { + OAuthValidationResponse oAuthValidationResponse = new OAuthValidationResponse(); + oAuthValidationResponse.setErrorMsg(tokenValidationResponse.getErrorMsg()); + return oAuthValidationResponse; + } + return new OAuthValidationResponse(userName,tenantDomain,isValid); + } +} diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/impl/RemoteOAuthValidator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/impl/RemoteOAuthValidator.java new file mode 100755 index 0000000000..1a6142f390 --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/oauth/impl/RemoteOAuthValidator.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.webapp.authenticator.framework.authenticator.oauth.impl; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.ServiceClient; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.httpclient.Header; +import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub; +import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO; +import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO_OAuth2AccessToken; +import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO_TokenValidationContextParam; +import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationResponseDTO; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuth2TokenValidator; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthConstants; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthTokenValidationException; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthValidationResponse; + +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the OAuth2 token validation from remote IS servers using remote OAuthValidation service-stub. + */ +public class RemoteOAuthValidator implements OAuth2TokenValidator { + + private String hostURL; + private String adminUserName; + private String adminPassword; + + public RemoteOAuthValidator(String hostURL, String adminUserName, String adminPassword) { + this.hostURL = hostURL; + this.adminUserName = adminUserName; + this.adminPassword = adminPassword; + } + + private String getBasicAuthCredentials() { + byte[] bytesEncoded = Base64.encodeBase64((adminUserName + ":" + adminPassword).getBytes()); + return new String(bytesEncoded); + } + + @Override + public OAuthValidationResponse validateToken(String accessToken, String resource) throws + OAuthTokenValidationException { + OAuth2TokenValidationRequestDTO validationRequest = new OAuth2TokenValidationRequestDTO(); + OAuth2TokenValidationRequestDTO_OAuth2AccessToken oauthToken = + new OAuth2TokenValidationRequestDTO_OAuth2AccessToken(); + oauthToken.setTokenType(OAuthConstants.BEARER_TOKEN_TYPE); + oauthToken.setIdentifier(accessToken); + validationRequest.setAccessToken(oauthToken); + + //Set the resource context param. This will be used in scope validation. + OAuth2TokenValidationRequestDTO_TokenValidationContextParam resourceContextParam = new + OAuth2TokenValidationRequestDTO_TokenValidationContextParam(); + resourceContextParam.setKey(OAuthConstants.RESOURCE_KEY); + resourceContextParam.setValue(resource); + + OAuth2TokenValidationRequestDTO_TokenValidationContextParam[] tokenValidationContextParams = + new OAuth2TokenValidationRequestDTO_TokenValidationContextParam[1]; + tokenValidationContextParams[0] = resourceContextParam; + validationRequest.setContext(tokenValidationContextParams); + + OAuth2TokenValidationServiceStub tokenValidationService; + try { + tokenValidationService = new OAuth2TokenValidationServiceStub(hostURL); + } catch (AxisFault axisFault) { + throw new OAuthTokenValidationException("Exception occurred while obtaining the " + + "OAuth2TokenValidationServiceStub.", axisFault); + } + ServiceClient client = tokenValidationService._getServiceClient(); + Options options = client.getOptions(); + List
headerList = new ArrayList<>(); + Header header = new Header(); + header.setName(HTTPConstants.HEADER_AUTHORIZATION); + header.setValue(OAuthConstants.AUTHORIZATION_HEADER_PREFIX_BASIC + " " + getBasicAuthCredentials()); + headerList.add(header); + options.setProperty(HTTPConstants.HTTP_HEADERS, headerList); + client.setOptions(options); + OAuth2TokenValidationResponseDTO tokenValidationResponse; + try { + tokenValidationResponse = tokenValidationService. + findOAuthConsumerIfTokenIsValid(validationRequest).getAccessTokenValidationResponse(); + } catch (RemoteException e) { + throw new OAuthTokenValidationException("Remote Exception occurred while invoking the Remote IS server for " + + "OAuth2 token validation.", e); + } + boolean isValid = tokenValidationResponse.getValid(); + String userName; + String tenantDomain; + if (isValid) { + userName = MultitenantUtils.getTenantAwareUsername( + tokenValidationResponse.getAuthorizedUser()); + tenantDomain = MultitenantUtils.getTenantDomain(tokenValidationResponse.getAuthorizedUser()); + } else { + OAuthValidationResponse oAuthValidationResponse = new OAuthValidationResponse(); + oAuthValidationResponse.setErrorMsg(tokenValidationResponse.getErrorMsg()); + return oAuthValidationResponse; + } + return new OAuthValidationResponse(userName,tenantDomain,isValid); + } +} 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 e09acd59ca..1fcb7a58c8 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 @@ -150,7 +150,7 @@ public class WebappAuthenticatorFrameworkServiceComponent { if (log.isDebugEnabled()) { log.debug("Setting OAuth2TokenValidationService Service"); } - AuthenticatorFrameworkDataHolder.getInstance().setoAuth2TokenValidationService(tokenValidationService); + AuthenticatorFrameworkDataHolder.getInstance().setOAuth2TokenValidationService(tokenValidationService); } /** @@ -162,6 +162,6 @@ public class WebappAuthenticatorFrameworkServiceComponent { if (log.isDebugEnabled()) { log.debug("Unsetting OAuth2TokenValidationService Service"); } - AuthenticatorFrameworkDataHolder.getInstance().setoAuth2TokenValidationService(null); + AuthenticatorFrameworkDataHolder.getInstance().setOAuth2TokenValidationService(null); } } diff --git a/pom.xml b/pom.xml index b85ea09489..e1cfad50d9 100644 --- a/pom.xml +++ b/pom.xml @@ -1491,7 +1491,7 @@ 4.6.0 - 5.0.2 + 5.0.3-SNAPSHOT 4.5.0