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/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 new file mode 100644 index 00000000000..7ef83a3fd94 --- /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,65 @@ +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 CERTIFICATE_VERIFICATION_HEADER = "certificate-verification-header"; + + @Override + public boolean canHandle(Request request) { + String certVerificationHeader = request.getContext().findParameter(CERTIFICATE_VERIFICATION_HEADER); + + if (certVerificationHeader != null && !certVerificationHeader.isEmpty()) { + + String certHeader = request.getHeader(certVerificationHeader); + + return certHeader != null; + } + + return false; + } + + @Override + public Status authenticate(Request request, Response response) { + + String requestUri = request.getRequestURI(); + if (requestUri == null || requestUri.isEmpty()) { + return Status.CONTINUE; + } + + String certVerificationHeader = request.getContext().findParameter(CERTIFICATE_VERIFICATION_HEADER); + + try { + 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); + return Status.FAILURE; + } + + return Status.FAILURE; + } + + @Override + public String getName() { + return CERTIFICATE_AUTHENTICATOR; + } +} 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 +