summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--aai-resources/pom.xml10
-rw-r--r--aai-resources/src/main/java/org/onap/aai/Profiles.java5
-rw-r--r--aai-resources/src/main/java/org/onap/aai/config/aaf/AafAuthorizationFilter.java68
-rw-r--r--aai-resources/src/main/java/org/onap/aai/config/aaf/AafFilter.java69
-rw-r--r--aai-resources/src/main/java/org/onap/aai/config/aaf/FilterPriority.java35
-rw-r--r--aai-resources/src/main/java/org/onap/aai/config/aaf/ResponseFormatter.java45
-rw-r--r--aai-resources/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java188
7 files changed, 231 insertions, 189 deletions
diff --git a/aai-resources/pom.xml b/aai-resources/pom.xml
index 603c1b1..c414070 100644
--- a/aai-resources/pom.xml
+++ b/aai-resources/pom.xml
@@ -494,6 +494,10 @@
<artifactId>aai-core</artifactId>
<exclusions>
<exclusion>
+ <groupId>org.onap.aai.aai-common</groupId>
+ <artifactId>aai-aaf-auth</artifactId>
+ </exclusion>
+ <exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
</exclusion>
@@ -518,6 +522,12 @@
<dependency>
<groupId>org.onap.aai.aai-common</groupId>
<artifactId>aai-schema-ingest</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.onap.aai.aai-common</groupId>
+ <artifactId>aai-aaf-auth</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
diff --git a/aai-resources/src/main/java/org/onap/aai/Profiles.java b/aai-resources/src/main/java/org/onap/aai/Profiles.java
index f35a4c9..25f51c3 100644
--- a/aai-resources/src/main/java/org/onap/aai/Profiles.java
+++ b/aai-resources/src/main/java/org/onap/aai/Profiles.java
@@ -25,7 +25,10 @@ public final class Profiles {
public static final String DME2 = "dme2";
public static final String ONE_WAY_SSL = "one-way-ssl";
-
+ // AAF Basic Auth
+ public static final String AAF_AUTHENTICATION = "aaf-auth";
+ // AAF Auth with Client Certs
+ public static final String AAF_CERT_AUTHENTICATION = "aaf-cert-auth";
public static final String TWO_WAY_SSL = "two-way-ssl";
private Profiles(){}
diff --git a/aai-resources/src/main/java/org/onap/aai/config/aaf/AafAuthorizationFilter.java b/aai-resources/src/main/java/org/onap/aai/config/aaf/AafAuthorizationFilter.java
new file mode 100644
index 0000000..51ad2ab
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/config/aaf/AafAuthorizationFilter.java
@@ -0,0 +1,68 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.config.aaf;
+
+import org.onap.aai.Profiles;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter;
+import org.springframework.context.annotation.Profile;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import static org.onap.aai.config.aaf.ResponseFormatter.errorResponse;
+
+/**
+ * AAF authorization filter
+ */
+
+@Component
+@Profile(Profiles.AAF_AUTHENTICATION)
+@PropertySource("file:${server.local.startpath}/aaf/permissions.properties")
+public class AafAuthorizationFilter extends OrderedRequestContextFilter {
+
+ @Value("${permission.type}")
+ String type;
+
+ @Value("${permission.instance}")
+ String instance;
+
+ public AafAuthorizationFilter() {
+ this.setOrder(FilterPriority.AAF_AUTHORIZATION.getPriority());
+ }
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
+ String permission = String.format("%s|%s|%s", type, instance, request.getMethod().toLowerCase());
+ if(request.getRequestURI().matches("^.*/util/echo$")){
+ filterChain.doFilter(request, response);
+ }
+ if(!request.isUserInRole(permission)){
+ errorResponse(request, response);
+ }else{
+ filterChain.doFilter(request,response);
+ }
+ }
+ }
diff --git a/aai-resources/src/main/java/org/onap/aai/config/aaf/AafFilter.java b/aai-resources/src/main/java/org/onap/aai/config/aaf/AafFilter.java
new file mode 100644
index 0000000..f7fd85c
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/config/aaf/AafFilter.java
@@ -0,0 +1,69 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.config.aaf;
+
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.filter.CadiFilter;
+import org.onap.aai.Profiles;
+import org.onap.aai.ResourcesApp;
+import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Properties;
+
+import static org.onap.aai.config.aaf.ResponseFormatter.*;
+
+/**
+ * AAF authentication filter
+ */
+
+@Component
+@Profile(Profiles.AAF_AUTHENTICATION)
+public class AafFilter extends OrderedRequestContextFilter {
+
+ private final CadiFilter cadiFilter;
+
+ public AafFilter() throws IOException, ServletException {
+ Properties cadiProperties = new Properties();
+ cadiProperties.load(ResourcesApp.class.getClassLoader().getResourceAsStream("cadi.properties"));
+ cadiFilter = new CadiFilter(new PropAccess(cadiProperties));
+ this.setOrder(FilterPriority.AAF_AUTHENTICATION.getPriority());
+ }
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
+ if(!request.getRequestURI().matches("^.*/util/echo$")){
+ cadiFilter.doFilter(request, response, filterChain);
+ if(response.getStatus() >=400 && response.getStatus() < 500){
+ errorResponse(request, response);
+ }
+ } else {
+ filterChain.doFilter(request, response);
+ }
+ }
+
+
+}
diff --git a/aai-resources/src/main/java/org/onap/aai/config/aaf/FilterPriority.java b/aai-resources/src/main/java/org/onap/aai/config/aaf/FilterPriority.java
new file mode 100644
index 0000000..910db69
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/config/aaf/FilterPriority.java
@@ -0,0 +1,35 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.config.aaf;
+
+import org.springframework.core.Ordered;
+
+public enum FilterPriority {
+ AAF_AUTHENTICATION(Ordered.HIGHEST_PRECEDENCE),
+ AAF_AUTHORIZATION(Ordered.HIGHEST_PRECEDENCE + 1); //higher number = lower priority
+
+ private final int priority;
+
+ FilterPriority(final int p) {
+ priority = p;
+ }
+
+ public int getPriority() { return priority; }
+}
diff --git a/aai-resources/src/main/java/org/onap/aai/config/aaf/ResponseFormatter.java b/aai-resources/src/main/java/org/onap/aai/config/aaf/ResponseFormatter.java
new file mode 100644
index 0000000..9e09827
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/config/aaf/ResponseFormatter.java
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.config.aaf;
+
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.logging.ErrorLogHelper;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+
+class ResponseFormatter {
+
+ private static final String ACCEPT_HEADER = "accept";
+
+ static void errorResponse(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ String accept = request.getHeader(ACCEPT_HEADER) == null ? MediaType.APPLICATION_XML : request.getHeader(ACCEPT_HEADER);
+ AAIException aaie = new AAIException("AAI_3300");
+ response.setStatus(aaie.getErrorObject().getHTTPResponseCode().getStatusCode());
+ response.getWriter().write(ErrorLogHelper.getRESTAPIErrorResponse(Collections.singletonList(MediaType.valueOf(accept)), aaie, new ArrayList<>()));
+ response.getWriter().flush();
+ response.getWriter().close();
+ }
+
+}
diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java
deleted file mode 100644
index 6c1c9f8..0000000
--- a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed 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.
- * ============LICENSE_END=========================================================
- */
-package org.onap.aai.interceptors.pre;
-
-import java.io.IOException;
-import java.security.cert.X509Certificate;
-import java.util.*;
-import java.util.stream.Collectors;
-
-import javax.annotation.Priority;
-import javax.security.auth.x500.X500Principal;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
-import javax.ws.rs.container.PreMatching;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.onap.aai.aaf.auth.AAIAuthCore;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.interceptors.AAIContainerFilter;
-import org.onap.aai.interceptors.AAIHeaderProperties;
-import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.restcore.HttpMethod;
-import org.onap.aai.util.AAIConfig;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
-
-@PreMatching
-@Priority(AAIRequestFilterPriority.AUTHORIZATION)
-@Profile("two-way-ssl")
-public class TwoWaySslAuthorization extends AAIContainerFilter implements ContainerRequestFilter {
-
- @Autowired
- private HttpServletRequest httpServletRequest;
-
- @Autowired
- private AAIAuthCore aaiAuthCore;
-
- @Override
- public void filter(ContainerRequestContext requestContext) {
-
- Optional<Response> oResp;
-
- String uri = requestContext.getUriInfo().getAbsolutePath().getPath();
- String httpMethod = getHttpMethod(requestContext);
-
- List<MediaType> acceptHeaderValues = requestContext.getAcceptableMediaTypes();
-
- Optional<String> authUser = getUser(this.httpServletRequest);
-
- if (authUser.isPresent()) {
- oResp = this.authorize(uri, httpMethod, acceptHeaderValues, authUser.get(),
- this.getHaProxyUser(this.httpServletRequest), getCertIssuer(this.httpServletRequest));
- if (oResp.isPresent()) {
- requestContext.abortWith(oResp.get());
- return;
- }
- } else {
- AAIException aaie = new AAIException("AAI_9107");
- requestContext
- .abortWith(Response
- .status(aaie.getErrorObject().getHTTPResponseCode()).entity(ErrorLogHelper
- .getRESTAPIErrorResponseWithLogging(acceptHeaderValues, aaie, new ArrayList<>()))
- .build());
- }
-
- }
-
- private String getCertIssuer(HttpServletRequest hsr) {
- String issuer = hsr.getHeader("X-AAI-SSL-Issuer");
- if (issuer != null && !issuer.isEmpty()) {
- // the haproxy header replaces the ', ' with '/' and reverses on the '/' need to undo that.
- List<String> broken = Arrays.asList(issuer.split("/"));
- broken = broken.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
- Collections.reverse(broken);
- issuer = String.join(", ", broken);
- } else {
- if (hsr.getAttribute("javax.servlet.request.cipher_suite") != null) {
- X509Certificate[] certChain = (X509Certificate[]) hsr.getAttribute("javax.servlet.request.X509Certificate");
- if (certChain != null && certChain.length > 0) {
- X509Certificate clientCert = certChain[0];
- issuer = clientCert.getIssuerX500Principal().getName();
- }
- }
- }
- return issuer;
- }
-
- private String getHttpMethod(ContainerRequestContext requestContext) {
- String httpMethod = requestContext.getMethod();
- if ("POST".equalsIgnoreCase(httpMethod)
- && "PATCH".equals(requestContext.getHeaderString(AAIHeaderProperties.HTTP_METHOD_OVERRIDE))) {
- httpMethod = HttpMethod.MERGE_PATCH.toString();
- }
- if (httpMethod.equalsIgnoreCase(HttpMethod.MERGE_PATCH.toString()) || "patch".equalsIgnoreCase(httpMethod)) {
- httpMethod = HttpMethod.PUT.toString();
- }
- return httpMethod;
- }
-
- private Optional<String> getUser(HttpServletRequest hsr) {
- String authUser = null;
- if (hsr.getAttribute("javax.servlet.request.cipher_suite") != null) {
- X509Certificate[] certChain = (X509Certificate[]) hsr.getAttribute("javax.servlet.request.X509Certificate");
-
- /*
- * If the certificate is null or the certificate chain length is zero Then
- * retrieve the authorization in the request header Authorization Check that it
- * is not null and that it starts with Basic and then strip the basic portion to
- * get the base64 credentials Check if this is contained in the AAIBasicAuth
- * Singleton class If it is, retrieve the username associated with that
- * credentials and set to authUser Otherwise, get the principal from certificate
- * and use that authUser
- */
-
- if (certChain == null || certChain.length == 0) {
-
- String authorization = hsr.getHeader("Authorization");
-
- if (authorization != null && authorization.startsWith("Basic ")) {
- authUser = authorization.replace("Basic ", "");
- }
-
- } else {
- X509Certificate clientCert = certChain[0];
- X500Principal subjectDN = clientCert.getSubjectX500Principal();
- authUser = subjectDN.toString().toLowerCase();
- }
- }
-
- return Optional.ofNullable(authUser);
- }
-
- private String getHaProxyUser(HttpServletRequest hsr) {
- String haProxyUser;
- if (Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-CN"))
- || Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-OU"))
- || Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-O"))
- || Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-L"))
- || Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-ST"))
- || Objects.isNull(hsr.getHeader("X-AAI-SSL-Client-C"))) {
- haProxyUser = "";
- } else {
- haProxyUser = String.format("CN=%s, OU=%s, O=\"%s\", L=%s, ST=%s, C=%s",
- Objects.toString(hsr.getHeader("X-AAI-SSL-Client-CN"), ""),
- Objects.toString(hsr.getHeader("X-AAI-SSL-Client-OU"), ""),
- Objects.toString(hsr.getHeader("X-AAI-SSL-Client-O"), ""),
- Objects.toString(hsr.getHeader("X-AAI-SSL-Client-L"), ""),
- Objects.toString(hsr.getHeader("X-AAI-SSL-Client-ST"), ""),
- Objects.toString(hsr.getHeader("X-AAI-SSL-Client-C"), "")).toLowerCase();
- }
- return haProxyUser;
- }
-
- private Optional<Response> authorize(String uri, String httpMethod, List<MediaType> acceptHeaderValues,
- String authUser, String haProxyUser, String issuer) {
- Response response = null;
- try {
- if (!aaiAuthCore.authorize(authUser, uri, httpMethod, haProxyUser, issuer)) {
- throw new AAIException("AAI_9101", "Request on " + httpMethod + " " + uri + " status is not OK");
- }
- } catch (AAIException e) {
- response = Response.status(e.getErrorObject().getHTTPResponseCode())
- .entity(ErrorLogHelper.getRESTAPIErrorResponseWithLogging(acceptHeaderValues, e, new ArrayList<>()))
- .build();
- }
- return Optional.ofNullable(response);
- }
-
-}