summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInstrumental <jonathan.gathman@att.com>2018-11-09 17:50:40 -0600
committerInstrumental <jonathan.gathman@att.com>2018-11-09 17:50:46 -0600
commit6c1d717147400ebda2b6e8713bbbb6c309702aa7 (patch)
tree98b031e59b0b3021e96ac41b02ab868c35e338ec
parent2c79dd1a45f46768bf908d9246f4480a7531974a (diff)
CADI Enforcement Point
Issue-ID: AAF-623 Change-Id: Ib49b68fe8323af895b80a90537e7d1c75bc46b70 Signed-off-by: Instrumental <jonathan.gathman@att.com>
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/validation/Validator.java2
-rw-r--r--cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/PermEval.java2
-rw-r--r--cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java3
-rw-r--r--cadi/aaf/src/test/java/org/onap/aaf/cadi/aaf/test/JU_PermEval.java2
-rw-r--r--cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java5
-rw-r--r--cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiApiEnforcementFilter.java132
-rw-r--r--cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java27
-rw-r--r--cadi/core/src/main/java/org/onap/aaf/cadi/filter/SideChain.java73
8 files changed, 225 insertions, 21 deletions
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/validation/Validator.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/validation/Validator.java
index 1c9f4123..7e861eda 100644
--- a/auth/auth-core/src/main/java/org/onap/aaf/auth/validation/Validator.java
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/validation/Validator.java
@@ -155,7 +155,7 @@ public class Validator {
}
public final Validator permInstance(String instance) {
- if (nob(instance,instChars)) {
+ if(!"/".equals(instance) && nob(instance,instChars)) {
msg("Perm Instance [" + instance + "] is invalid.");
}
return this;
diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/PermEval.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/PermEval.java
index c12b2e6d..2c7aa12b 100644
--- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/PermEval.java
+++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/PermEval.java
@@ -77,7 +77,7 @@ public class PermEval {
if (pass=sItem.length()==0) {
break; // Both Empty, keep checking
}
- } else if (sItem.charAt(0)==START_REGEX_CHAR) { // Check Server side when wildcarding like *
+ } else if (sItem.length()>0 && sItem.charAt(0)==START_REGEX_CHAR) { // Check Server side when wildcarding like *
if (pass=pkeys[i].matches(sItem.substring(1))) {
break; // Matches, keep checking
}
diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java
index c27dd123..ea404400 100644
--- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java
+++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java
@@ -93,8 +93,9 @@ public class AAFTaf<CLIENT> extends AbsUserCache<AAFPermission> implements HttpT
} else {
try {
mapIds = new MapBathConverter(access, new CSV(csvFile));
+ access.log(Level.INIT,"Basic Auth Conversion using",csvFile,"enabled" );
} catch (IOException | CadiException e) {
- access.log(e,"Bath Map Conversion is not initialzed (non fatal)");
+ access.log(e,"Bath Map Conversion is not initialized (non fatal)");
}
}
diff --git a/cadi/aaf/src/test/java/org/onap/aaf/cadi/aaf/test/JU_PermEval.java b/cadi/aaf/src/test/java/org/onap/aaf/cadi/aaf/test/JU_PermEval.java
index a6c0f916..3e137c25 100644
--- a/cadi/aaf/src/test/java/org/onap/aaf/cadi/aaf/test/JU_PermEval.java
+++ b/cadi/aaf/src/test/java/org/onap/aaf/cadi/aaf/test/JU_PermEval.java
@@ -74,6 +74,8 @@ public class JU_PermEval {
// Accept matching empty keys
assertThat(PermEval.evalInstance(":", ":"), is(true));
+ assertThat(PermEval.evalInstance("/", "/"), is(true));
+ assertThat(PermEval.evalInstance("/something/", "/something/"), is(true));
// Reject non-matching empty keys
assertThat(PermEval.evalInstance(":fred", ":"), is(false));
diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java
index 3d668c42..0e4f72b8 100644
--- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java
+++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java
@@ -103,7 +103,10 @@ public class Config {
public static final String CADI_PROTOCOLS = "cadi_protocols";
public static final String CADI_NOAUTHN = "cadi_noauthn";
public static final String CADI_LOC_LIST = "cadi_loc_list";
+
+ // Special Behaviors
public static final String CADI_BATH_CONVERT = "cadi_bath_convert";
+ public static final String CADI_API_ENFORCEMENT = "cadi_api_enforcement";
public static final String CADI_USER_CHAIN_TAG = "cadi_user_chain";
public static final String CADI_USER_CHAIN = "USER_CHAIN";
@@ -410,7 +413,7 @@ public class Config {
oadtClss = Class.forName(OAUTH_DIRECT_TAF);
} catch (ClassNotFoundException e1) {
oadtClss = null;
- access.log(Level.INIT, e1);
+ access.log(Level.DEBUG, e1);
}
if (additionalTafLurs!=null && additionalTafLurs.length>0 && (oadtClss!=null && additionalTafLurs[0].getClass().isAssignableFrom(oadtClss))) {
htlist.add((HttpTaf)additionalTafLurs[0]);
diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiApiEnforcementFilter.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiApiEnforcementFilter.java
new file mode 100644
index 00000000..495131b9
--- /dev/null
+++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiApiEnforcementFilter.java
@@ -0,0 +1,132 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 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.aaf.cadi.filter;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.ServletContextAccess;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.cadi.util.Split;
+
+/**
+ * This filter allows one to protect the APIs from data stored in AAF
+ *
+ * @author Instrumental(Jonathan)
+ */
+public class CadiApiEnforcementFilter implements Filter {
+ private String type;
+ private Map<String,List<String>> publicPaths;
+ private Access access;
+
+
+ public CadiApiEnforcementFilter(Access access, String enforce) throws ServletException {
+ this.access = access;
+ init(enforce);
+ }
+
+
+ @Override
+ public void init(FilterConfig fc) throws ServletException {
+ init(fc.getInitParameter(Config.CADI_API_ENFORCEMENT));
+ // need the Context for Logging, instantiating ClassLoader, etc
+ ServletContextAccess sca=new ServletContextAccess(fc);
+ if (access==null) {
+ access = sca;
+ }
+ }
+
+ private void init(final String ptypes) throws ServletException {
+ if(ptypes==null) {
+ throw new ServletException("CadiApiEnforcement requires " + Config.CADI_API_ENFORCEMENT + " property");
+ }
+ String[] full = Split.splitTrim(';', ptypes);
+ if(full.length==0) {
+ throw new ServletException(Config.CADI_API_ENFORCEMENT + " property is empty");
+ }
+ if(full.length>0) {
+ type=full[0];
+ }
+ publicPaths = new TreeMap<String,List<String>>();
+ if(full.length>1) {
+ for(int i=1;i<full.length;++i) {
+ String pubArray[] = Split.split(':', full[i]);
+ if(pubArray.length==2) {
+ List<String> ls = publicPaths.get(pubArray[0]);
+ if(ls==null) {
+ ls = new ArrayList<String>();
+ publicPaths.put(pubArray[0], ls);
+ }
+ ls.add(pubArray[1]);
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain fc) throws IOException, ServletException {
+ HttpServletRequest hreq = (HttpServletRequest)req;
+ final String meth = hreq.getMethod();
+ final String path = hreq.getContextPath()+hreq.getPathInfo();
+ List<String> list = publicPaths.get(meth);
+ if(list!=null) {
+ for( String p : publicPaths.get(meth)) {
+ if(path.startsWith(p)) {
+ access.printf(Level.INFO, "%s accessed public API %s %s\n",
+ hreq.getUserPrincipal().getName(),
+ meth,
+ path);
+ fc.doFilter(req, resp);
+ return;
+ }
+ }
+ }
+ if(hreq.isUserInRole(type + '|'+path+'|'+meth)) {
+ access.printf(Level.INFO, "%s is allowed access to %s %s\n",
+ hreq.getUserPrincipal().getName(),
+ meth,
+ path);
+ fc.doFilter(req, resp);
+ } else {
+ access.printf(Level.AUDIT, "%s is denied access to %s %s\n",
+ hreq.getUserPrincipal().getName(),
+ meth,
+ path);
+ }
+ }
+
+ @Override
+ public void destroy() {
+ }
+}
diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java
index cd48556b..2305eacd 100644
--- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java
+++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java
@@ -71,7 +71,7 @@ public class CadiFilter implements Filter {
private static List<Pair> mapPairs;
private Access access;
private Object[] additionalTafLurs;
- private Filter oauthFilter;
+ private SideChain sideChain;
private static int count=0;
public Lur getLur() {
@@ -140,6 +140,7 @@ public class CadiFilter implements Filter {
@SuppressWarnings("unchecked")
private void init(Get getter) throws ServletException {
+ sideChain = new SideChain();
// Start with the assumption of "Don't trust anyone".
TrustChecker tc = TrustChecker.NOTRUST; // default position
try {
@@ -158,22 +159,9 @@ public class CadiFilter implements Filter {
Class<Filter> cf=null;
try {
cf= (Class<Filter>) Class.forName("org.onap.aaf.cadi.oauth.OAuthFilter");
- oauthFilter = cf.newInstance();
+ sideChain.add(cf.newInstance());
} catch (ClassNotFoundException e) {
- oauthFilter = new Filter() { // Null Filter
- @Override
- public void destroy() {
- }
-
- @Override
- public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)throws IOException, ServletException {
- chain.doFilter(req, resp);
- }
-
- @Override
- public void init(FilterConfig arg0) throws ServletException {
- }
- };
+ access.log(Level.DEBUG, "OAuthFilter not enabled");
}
} catch (Exception e) {
access.log(Level.INIT, "AAFTrustChecker cannot be loaded",e.getMessage());
@@ -238,6 +226,11 @@ public class CadiFilter implements Filter {
}
}
+ // Add API Enforcement Point
+ String enforce = getter.get(Config.CADI_API_ENFORCEMENT, null, true);
+ if(enforce!=null && enforce.length()>0) {
+ sideChain.add(new CadiApiEnforcementFilter(access,enforce));
+ }
// Remove Getter
getter = Get.NULL;
}
@@ -287,7 +280,7 @@ public class CadiFilter implements Filter {
CadiWrap cw = new CadiWrap(hreq, tresp, httpChecker.getLur(),getConverter(hreq));
if (httpChecker.notCadi(cw, hresp)) {
startCode=System.nanoTime();
- oauthFilter.doFilter(cw,response,chain);
+ sideChain.doFilter(cw,response,chain);
code = Timing.millis(startCode);
}
}
diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/SideChain.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/SideChain.java
new file mode 100644
index 00000000..8283b4dd
--- /dev/null
+++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/SideChain.java
@@ -0,0 +1,73 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 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.aaf.cadi.filter;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.xml.ws.Holder;
+
+/**
+ * Add various Filters by CADI Property not in the official Chain
+ *
+ * @author Instrumental(Jonathan)
+ *
+ */
+public class SideChain {
+ private List<Filter> sideChain;
+
+ public SideChain() {
+ sideChain = new ArrayList<Filter>();
+ }
+
+ public void add(Filter f) {
+ sideChain.add(f);
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
+ final Holder<Boolean> hbool = new Holder<Boolean>(Boolean.TRUE);
+ FilterChain truth = new FilterChain() {
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
+ hbool.value=Boolean.TRUE;
+ }
+ public String toString() {
+ return hbool.value.toString();
+ }
+ };
+ for(Filter f : sideChain) {
+ hbool.value=Boolean.FALSE;
+ f.doFilter(request, response, truth);
+ if(!hbool.value) {
+ return;
+ }
+ }
+ if(hbool.value) {
+ chain.doFilter(request, response);
+ }
+ }
+}