aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZlatko Murgoski <zlatko.murgoski@nokia.com>2019-04-17 10:10:30 +0200
committerZlatko Murgoski <zlatko.murgoski@nokia.com>2019-04-18 11:04:53 +0200
commit5caf0800a080d3ac4fb9573b319336160b2ebcba (patch)
treefb115d6b4e0e35b3ec91e86f39de3d16992b2488
parentff4bf8d97be17232187dfdbb5fc913d015b3b213 (diff)
VES Collector - certBasicAuth1.4.4
https://jira.onap.org/browse/DCAEGEN2-1440 Issue-ID: DCAEGEN2-1440 Change-Id: I7976d03c65e261930533a49a6716fd6161124ad9 Signed-off-by: Zlatko Murgoski <zlatko.murgoski@nokia.com>
-rw-r--r--src/main/java/org/onap/dcae/common/configuration/CertAuth.java29
-rw-r--r--src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java32
-rw-r--r--src/main/java/org/onap/dcae/common/configuration/SubjectMatcher.java (renamed from src/main/java/org/onap/dcae/common/configuration/CustomFilter.java)44
-rw-r--r--src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java64
-rw-r--r--src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java2
5 files changed, 66 insertions, 105 deletions
diff --git a/src/main/java/org/onap/dcae/common/configuration/CertAuth.java b/src/main/java/org/onap/dcae/common/configuration/CertAuth.java
index 481fb5ec..6bd924c3 100644
--- a/src/main/java/org/onap/dcae/common/configuration/CertAuth.java
+++ b/src/main/java/org/onap/dcae/common/configuration/CertAuth.java
@@ -21,24 +21,15 @@
package org.onap.dcae.common.configuration;
-import org.onap.dcae.ApplicationException;
import org.onap.dcae.ApplicationSettings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.server.Ssl.ClientAuth;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Configuration;
-import org.springframework.core.annotation.Order;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.builders.WebSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
@Configuration
-@Order(0)
-@EnableWebSecurity
-public class CertAuth extends WebSecurityConfigurerAdapter implements AuthMethod {
+public class CertAuth implements AuthMethod {
private static final Logger log = LoggerFactory.getLogger(CertAuth.class);
private final ConfigurableServletWebServerFactory container;
@@ -50,24 +41,6 @@ public class CertAuth extends WebSecurityConfigurerAdapter implements AuthMethod
}
@Override
- public void configure(WebSecurity web) {
- web.ignoring().anyRequest();
- }
-
- @Override
- protected void configure(HttpSecurity http) {
- try {
- http.authorizeRequests()
- .anyRequest().authenticated().and()
- .addFilterBefore(new CustomFilter(properties), FilterSecurityInterceptor.class);
-
- } catch (Exception ex) {
- log.error("Cannot authorize request cause: ",ex);
- throw new ApplicationException(ex);
- }
- }
-
- @Override
public void configure() {
SslContextCreator sslContextCreator = new SslContextCreator(properties);
container.setSsl(sslContextCreator.httpsContextWithTlsAuthentication(ClientAuth.NEED));
diff --git a/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java b/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java
index c9e0af41..38d5ad5b 100644
--- a/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java
+++ b/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java
@@ -21,24 +21,15 @@
package org.onap.dcae.common.configuration;
-import org.onap.dcae.ApplicationException;
import org.onap.dcae.ApplicationSettings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.server.Ssl.ClientAuth;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Configuration;
-import org.springframework.core.annotation.Order;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.builders.WebSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
@Configuration
-@Order(1)
-@EnableWebSecurity
-public class CertBasicAuth extends WebSecurityConfigurerAdapter implements AuthMethod{
+public class CertBasicAuth implements AuthMethod{
private static final Logger log = LoggerFactory.getLogger(CertAuth.class);
private final ConfigurableServletWebServerFactory container;
@@ -50,24 +41,6 @@ public class CertBasicAuth extends WebSecurityConfigurerAdapter implements AuthM
}
@Override
- public void configure(WebSecurity web) {
- web.ignoring().anyRequest();
- }
-
- @Override
- protected void configure(HttpSecurity http) {
- try {
- http.authorizeRequests()
- .anyRequest().authenticated().and()
- .addFilterBefore(new CustomFilter(properties), FilterSecurityInterceptor.class);
-
- } catch (Exception ex) {
- log.error("Cannot authorize request cause: ",ex);
- throw new ApplicationException(ex);
- }
- }
-
- @Override
public void configure() {
SslContextCreator sslContextCreator = new SslContextCreator(properties);
container.setPort(properties.httpsPort());
@@ -75,5 +48,4 @@ public class CertBasicAuth extends WebSecurityConfigurerAdapter implements AuthM
log.info(String.format("Application work in %s mode on %s port.",
properties.authMethod(), properties.httpsPort()));
}
-}
-
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/dcae/common/configuration/CustomFilter.java b/src/main/java/org/onap/dcae/common/configuration/SubjectMatcher.java
index ae693fa6..9ab42211 100644
--- a/src/main/java/org/onap/dcae/common/configuration/CustomFilter.java
+++ b/src/main/java/org/onap/dcae/common/configuration/SubjectMatcher.java
@@ -28,47 +28,29 @@ import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
+import org.onap.dcae.ApplicationException;
import org.onap.dcae.ApplicationSettings;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.filter.GenericFilterBean;
-@Configuration
-public class CustomFilter extends GenericFilterBean {
+public class SubjectMatcher {
- private static final String CERTIFICATE_X_509 = "javax.servlet.request.X509Certificate";
- private static final String MESSAGE = "SubjectDN didn't match with any regexp from %s file like %s";
- private ApplicationSettings properties;
+ private final ApplicationSettings properties;
+ private final X509Certificate[] cert;
- public CustomFilter(ApplicationSettings properties) {
+ public SubjectMatcher(ApplicationSettings properties, X509Certificate[] cert) {
this.properties = properties;
+ this.cert = cert;
}
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
- FilterChain filterChain) throws IOException, ServletException {
-
- X509Certificate[] cert = (X509Certificate[]) servletRequest.getAttribute(CERTIFICATE_X_509);
-
- if (cert != null) {
- if (getLines().anyMatch(element -> Pattern.compile(element).matcher(getSubjectDN(cert)).find())) {
- filterChain.doFilter(servletRequest, servletResponse);
- } else {
- setResponse((HttpServletResponse) servletResponse);
- }
- } else {
- filterChain.doFilter(servletRequest, servletResponse);
+ public boolean match(){
+ try {
+ return getLines().anyMatch(element -> Pattern.compile(element).matcher(getSubjectDN(cert)).find());
+ } catch (IOException ex) {
+ throw new ApplicationException("Cannot read file cause: ", ex);
}
}
- private void setResponse(HttpServletResponse servletResponse) throws IOException {
- HttpServletResponse response = servletResponse;
- response.sendError(HttpServletResponse.SC_FORBIDDEN,
- String.format(MESSAGE, properties.certSubjectMatcher(), getLines().collect(Collectors.joining(" "))));
+ public boolean isCert() {
+ return cert !=null;
}
private Stream<String> getLines() throws IOException {
diff --git a/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java b/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java
index bb290575..7d3d2929 100644
--- a/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java
+++ b/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java
@@ -21,11 +21,14 @@ package org.onap.dcae.restapi;
import io.vavr.control.Option;
import java.io.IOException;
+import java.security.cert.X509Certificate;
import java.util.Base64;
+import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.onap.dcae.ApplicationSettings;
import org.onap.dcae.common.configuration.AuthMethodType;
+import org.onap.dcae.common.configuration.SubjectMatcher;
import org.onap.dcaegen2.services.sdk.security.CryptPassword;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,11 +37,12 @@ import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
final class ApiAuthInterceptor extends HandlerInterceptorAdapter {
private static final Logger LOG = LoggerFactory.getLogger(ApiAuthInterceptor.class);
+ private static final String CERTIFICATE_X_509 = "javax.servlet.request.X509Certificate";
+ private static final String MESSAGE = "SubjectDN didn't match with any regexp from %s";
private final CryptPassword cryptPassword = new CryptPassword();
private final ApplicationSettings settings;
private Logger errorLogger;
-
public ApiAuthInterceptor(ApplicationSettings applicationSettings, Logger errorLogger) {
this.settings = applicationSettings;
this.errorLogger = errorLogger;
@@ -48,25 +52,55 @@ final class ApiAuthInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws IOException {
- if(settings.authMethod().equalsIgnoreCase(AuthMethodType.CERT_BASIC_AUTH.value())){
- if (request.getAttribute("javax.servlet.request.X509Certificate") != null){
- LOG.info("Request is authorized by certificate ");
- return true;
- }
+ SubjectMatcher subjectMatcher = new SubjectMatcher(settings,(X509Certificate[]) request.getAttribute(CERTIFICATE_X_509));
+
+ if(settings.authMethod().equalsIgnoreCase(AuthMethodType.CERT_ONLY.value())){
+ return validateCertRequest(response, subjectMatcher);
+ }
+
+ if(isCertSubject(subjectMatcher)){
+ return true;
+ }
+
+ if (isBasicAuth() ) {
+ return validateBasicHeader(request, response);
+ }
+ return true;
+ }
+
+ private boolean validateBasicHeader(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ String authorizationHeader = request.getHeader("Authorization");
+ if (authorizationHeader == null || !isAuthorized(authorizationHeader)) {
+ response.setStatus(401);
+ errorLogger.error("EVENT_RECEIPT_FAILURE: Unauthorized user");
+ response.getWriter().write(ApiException.UNAUTHORIZED_USER.toJSON().toString());
+ return false;
}
- if (isBasicAuth()) {
- String authorizationHeader = request.getHeader("Authorization");
- if (authorizationHeader == null || !isAuthorized(authorizationHeader)) {
- response.setStatus(401);
- errorLogger.error("EVENT_RECEIPT_FAILURE: Unauthorized user");
- response.getWriter().write(ApiException.UNAUTHORIZED_USER.toJSON().toString());
- return false;
- }
- LOG.info("Request is authorized by basic auth");
+ LOG.info("Request is authorized by basic auth");
+ return true;
+ }
+
+ private boolean validateCertRequest(HttpServletResponse response, SubjectMatcher subjectMatcher)
+ throws IOException {
+ if (!isCertSubject(subjectMatcher)) {
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+ response.getWriter().write(String.format(MESSAGE, settings.certSubjectMatcher()));
+ return false;
}
+ LOG.info("Cert and subjectDN is valid");
return true;
}
+ private boolean isCertSubject(SubjectMatcher subjectMatcher) {
+ if(subjectMatcher.isCert() && subjectMatcher.match()){
+ LOG.info("Cert and subjectDN is valid");
+ return true;
+ }
+ LOG.info(String.format(MESSAGE, settings.certSubjectMatcher()));
+ return false;
+ }
+
private boolean isBasicAuth() {
return settings.authMethod().equalsIgnoreCase(AuthMethodType.BASIC_AUTH.value())
|| settings.authMethod().equalsIgnoreCase(AuthMethodType.CERT_BASIC_AUTH.value());
diff --git a/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java b/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java
index a295046b..c0a06a07 100644
--- a/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java
+++ b/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java
@@ -140,7 +140,7 @@ public class ApiAuthInterceptionTest {
public void shouldSucceed() throws IOException {
// given
final HttpServletRequest request = createRequestWithAuthorizationHeader();
- when(settings.authMethod()).thenReturn(AuthMethodType.CERT_ONLY.value());
+ when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value());
when(settings.validAuthorizationCredentials()).thenReturn(
HashMap.of(USERNAME, "$2a$10$BsZkEynNm/93wbAeeZuxJeu6IHRyQl4XReqDg2BtYOFDhUsz20.3G"));
when(response.getWriter()).thenReturn(writer);