From d17f1356e7a4f5474d849c19417c59ed73585bb9 Mon Sep 17 00:00:00 2001 From: Dilshan Edirisuriya Date: Tue, 8 Sep 2015 17:21:23 +0530 Subject: [PATCH 1/2] Certificate authenticator changes --- .../pom.xml | 8 +- .../authenticator/framework/DataHolder.java | 10 +++ .../CertificateAuthenticator.java | 78 +++++++++++++++++++ ...uthenticatorFrameworkServiceComponent.java | 25 +++++- .../conf/webapp-authenticator-config.xml | 4 + 5 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java 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 edca5ac9554..2b7953b8cbf 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 @@ -92,7 +92,9 @@ javax.servlet.http, javax.xml, org.apache.axis2.transport.http, - org.wso2.carbon.apimgt.impl + org.wso2.carbon.apimgt.impl, + org.wso2.carbon.certificate.mgt.core.service, + org.wso2.carbon.certificate.mgt.core.exception @@ -146,6 +148,10 @@ org.wso2.orbit.com.nimbusds nimbus-jose-jwt + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/DataHolder.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/DataHolder.java index 12be00a5703..2ad358341d0 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/DataHolder.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/DataHolder.java @@ -18,12 +18,14 @@ */ package org.wso2.carbon.webapp.authenticator.framework; +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.user.core.service.RealmService; public class DataHolder { private WebappAuthenticatorRepository repository; private RealmService realmService; + private CertificateManagementService certificateManagementService; private DataHolder() {} @@ -48,4 +50,12 @@ public class DataHolder { public void setRealmService(RealmService realmService) { this.realmService = realmService; } + + public CertificateManagementService getCertificateManagementService() { + return certificateManagementService; + } + + public void setCertificateManagementService(CertificateManagementService certificateManagementService) { + this.certificateManagementService = certificateManagementService; + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java new file mode 100644 index 00000000000..6916e21a346 --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java @@ -0,0 +1,78 @@ +package org.wso2.carbon.webapp.authenticator.framework.authenticator; + +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.certificate.mgt.core.exception.KeystoreException; +import org.wso2.carbon.webapp.authenticator.framework.DataHolder; + +/** + * This authenticator authenticates HTTP requests using certificates. + */ +public class CertificateAuthenticator implements WebappAuthenticator { + + private static final Log log = LogFactory.getLog(CertificateAuthenticator.class); + private static final String CERTIFICATE_AUTHENTICATOR = "CertificateAuth"; + private static final String HEADER_MDM_SIGNATURE = "Mdm-Signature"; + private String[] skippedURIs; + + public CertificateAuthenticator() { + skippedURIs = new String[]{ + "/ios-enrollment/ca", + "/ios-enrollment/authenticate", + "/ios-enrollment/profile", + "/ios-enrollment/scep", + "/ios-enrollment/enroll", + "/ios-enrollment/enrolled"}; + } + + @Override + public boolean canHandle(Request request) { + return true; + } + + @Override + public Status authenticate(Request request, Response response) { + + String requestUri = request.getRequestURI(); + if (requestUri == null || requestUri.isEmpty()) { + return Status.CONTINUE; + } + + if(isURISkipped(requestUri)) { + return Status.CONTINUE; + } + + String headerMDMSignature = request.getHeader(HEADER_MDM_SIGNATURE); + + try { + if (headerMDMSignature != null && !headerMDMSignature.isEmpty() && + DataHolder.getInstance().getCertificateManagementService().verifySignature(headerMDMSignature)) { + return Status.SUCCESS; + } + } catch (KeystoreException e) { + log.error("KeystoreException occurred ", e); + return Status.FAILURE; + } + + return Status.FAILURE; + } + + @Override + public String getName() { + return CERTIFICATE_AUTHENTICATOR; + } + + private boolean isURISkipped(String requestUri) { + + for (String element : skippedURIs) { + if (element.equals(requestUri)) { + return true; + } + } + + return false; + } + +} 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 e30d9ce6806..7b7935a1f95 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 @@ -21,14 +21,14 @@ package org.wso2.carbon.webapp.authenticator.framework.internal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve; import org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.webapp.authenticator.framework.DataHolder; import org.wso2.carbon.webapp.authenticator.framework.WebappAuthenticationHandler; -import org.wso2.carbon.webapp.authenticator.framework.authenticator.WebappAuthenticator; -import org.wso2.carbon.webapp.authenticator.framework.WebappAuthenticatorFrameworkValve; import org.wso2.carbon.webapp.authenticator.framework.WebappAuthenticatorRepository; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.WebappAuthenticator; import org.wso2.carbon.webapp.authenticator.framework.config.AuthenticatorConfig; import org.wso2.carbon.webapp.authenticator.framework.config.WebappAuthenticatorConfig; @@ -44,6 +44,12 @@ import java.util.List; * policy="dynamic" * bind="setRealmService" * unbind="unsetRealmService" + * @scr.reference name="org.wso2.carbon.certificate.mgt" + * interface="org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService" + * policy="dynamic" + * cardinality="1..n" + * bind="setCertificateManagementService" + * unbind="unsetCertificateManagementService" */ public class WebappAuthenticatorFrameworkServiceComponent { @@ -91,4 +97,19 @@ public class WebappAuthenticatorFrameworkServiceComponent { protected void unsetRealmService(RealmService realmService) { DataHolder.getInstance().setRealmService(null); } + + protected void setCertificateManagementService(CertificateManagementService certificateManagementService) { + if (log.isDebugEnabled()) { + log.debug("Setting certificate management service"); + } + DataHolder.getInstance().setCertificateManagementService(certificateManagementService); + } + + protected void unsetCertificateManagementService(CertificateManagementService certificateManagementService) { + if (log.isDebugEnabled()) { + log.debug("Removing certificate management service"); + } + + DataHolder.getInstance().setCertificateManagementService(null); + } } diff --git a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml index f42dde6271f..067d8cd3cea 100644 --- a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml +++ b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml @@ -12,5 +12,9 @@ JWT org.wso2.carbon.webapp.authenticator.framework.authenticator.JWTAuthenticator + + CertificateAuth + org.wso2.carbon.webapp.authenticator.framework.authenticator.CertificateAuthenticator + From e1a74e049dbebd513910e9ed69226f488d73c314 Mon Sep 17 00:00:00 2001 From: Dilshan Edirisuriya Date: Wed, 9 Sep 2015 17:16:26 +0530 Subject: [PATCH 2/2] Bypassing URLS --- .../WebappAuthenticationHandler.java | 23 ++++++++ .../WebappAuthenticatorFrameworkValve.java | 27 ++++++++-- .../CertificateAuthenticator.java | 53 +++++++------------ 3 files changed, 67 insertions(+), 36 deletions(-) diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationHandler.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationHandler.java index c700fb304f3..7eb98c0d55a 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationHandler.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationHandler.java @@ -27,18 +27,41 @@ import org.wso2.carbon.tomcat.ext.valves.CompositeValve; import org.wso2.carbon.webapp.authenticator.framework.authenticator.WebappAuthenticator; import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.List; import java.util.StringTokenizer; public class WebappAuthenticationHandler extends CarbonTomcatValve { private static final Log log = LogFactory.getLog(WebappAuthenticationHandler.class); + private static final String BYPASS_URIS = "bypass-uris"; @Override public void invoke(Request request, Response response, CompositeValve compositeValve) { + if (this.isContextSkipped(request) || (!this.isAdminService(request) && this.skipAuthentication(request))) { this.getNext().invoke(request, response, compositeValve); return; } + + String byPassURIs = request.getContext().findParameter(WebappAuthenticationHandler.BYPASS_URIS); + + if(byPassURIs != null && !byPassURIs.isEmpty()) { + + List requestURI = Arrays.asList(byPassURIs.split(",")); + + if(requestURI != null && requestURI.size() > 0) { + for (String pathURI : requestURI) { + pathURI = pathURI.replace("\n", "").replace("\r", "").trim(); + + if (request.getRequestURI().equals(pathURI)) { + this.getNext().invoke(request, response, compositeValve); + return; + } + } + } + } + WebappAuthenticator authenticator = WebappAuthenticatorFactory.getAuthenticator(request); if (authenticator == null) { String msg = "Failed to load an appropriate authenticator to authenticate the request"; diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticatorFrameworkValve.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticatorFrameworkValve.java index 3501c9e5945..1701c7d30c9 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticatorFrameworkValve.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticatorFrameworkValve.java @@ -27,20 +27,41 @@ import org.wso2.carbon.tomcat.ext.valves.CompositeValve; import org.wso2.carbon.webapp.authenticator.framework.authenticator.WebappAuthenticator; import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.List; public class WebappAuthenticatorFrameworkValve extends CarbonTomcatValve { private static final String AUTHENTICATION_SCHEME = "authentication-scheme"; + private static final String BYPASS_URIS = "bypass-uris"; private static final Log log = LogFactory.getLog(WebappAuthenticatorFrameworkValve.class); @Override public void invoke(Request request, Response response, CompositeValve compositeValve) { - String authScheme = - request.getContext().findParameter(WebappAuthenticatorFrameworkValve.AUTHENTICATION_SCHEME); - if (authScheme == null || "".equals(authScheme)) { + + String authScheme = request.getContext().findParameter(WebappAuthenticatorFrameworkValve.AUTHENTICATION_SCHEME); + + if (authScheme == null || authScheme.isEmpty()) { this.getNext().invoke(request, response, compositeValve); return; } + + String byPassURIs = request.getContext().findParameter(WebappAuthenticatorFrameworkValve.BYPASS_URIS); + + if(byPassURIs != null && !byPassURIs.isEmpty()) { + + List requestURI = Arrays.asList(byPassURIs.split(",")); + + if(requestURI != null && requestURI.size() > 0) { + for (String pathURI : requestURI) { + if (request.getRequestURI().equals(pathURI)) { + this.getNext().invoke(request, response, compositeValve); + return; + } + } + } + } + WebappAuthenticator authenticator = WebappAuthenticatorFactory.getAuthenticator(authScheme); if (authenticator == null) { String msg = "Failed to load an appropriate authenticator to authenticate the request"; diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java index 6916e21a346..7ef83a3fd94 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/CertificateAuthenticator.java @@ -14,22 +14,20 @@ public class CertificateAuthenticator implements WebappAuthenticator { private static final Log log = LogFactory.getLog(CertificateAuthenticator.class); private static final String CERTIFICATE_AUTHENTICATOR = "CertificateAuth"; - private static final String HEADER_MDM_SIGNATURE = "Mdm-Signature"; - private String[] skippedURIs; - - public CertificateAuthenticator() { - skippedURIs = new String[]{ - "/ios-enrollment/ca", - "/ios-enrollment/authenticate", - "/ios-enrollment/profile", - "/ios-enrollment/scep", - "/ios-enrollment/enroll", - "/ios-enrollment/enrolled"}; - } + private static final String CERTIFICATE_VERIFICATION_HEADER = "certificate-verification-header"; @Override public boolean canHandle(Request request) { - return true; + String certVerificationHeader = request.getContext().findParameter(CERTIFICATE_VERIFICATION_HEADER); + + if (certVerificationHeader != null && !certVerificationHeader.isEmpty()) { + + String certHeader = request.getHeader(certVerificationHeader); + + return certHeader != null; + } + + return false; } @Override @@ -40,16 +38,17 @@ public class CertificateAuthenticator implements WebappAuthenticator { return Status.CONTINUE; } - if(isURISkipped(requestUri)) { - return Status.CONTINUE; - } - - String headerMDMSignature = request.getHeader(HEADER_MDM_SIGNATURE); + String certVerificationHeader = request.getContext().findParameter(CERTIFICATE_VERIFICATION_HEADER); try { - if (headerMDMSignature != null && !headerMDMSignature.isEmpty() && - DataHolder.getInstance().getCertificateManagementService().verifySignature(headerMDMSignature)) { - return Status.SUCCESS; + if (certVerificationHeader != null && !certVerificationHeader.isEmpty()) { + + String certHeader = request.getHeader(certVerificationHeader); + + if (certHeader != null && DataHolder.getInstance().getCertificateManagementService(). + verifySignature(certHeader)) { + return Status.SUCCESS; + } } } catch (KeystoreException e) { log.error("KeystoreException occurred ", e); @@ -63,16 +62,4 @@ public class CertificateAuthenticator implements WebappAuthenticator { public String getName() { return CERTIFICATE_AUTHENTICATOR; } - - private boolean isURISkipped(String requestUri) { - - for (String element : skippedURIs) { - if (element.equals(requestUri)) { - return true; - } - } - - return false; - } - }