From 62c4eb45e157d502463d797c1353802ca8e1e307 Mon Sep 17 00:00:00 2001 From: sg481n Date: Fri, 25 Aug 2017 01:57:24 -0400 Subject: Update project structure for aaf/cadi Update project structure from com.att to org.onap and add distribution management and staging plugin. Issue-id: AAF-22 Change-Id: Idf2b591139e38921ad28782a51486714a05dee92 Signed-off-by: sg481n --- .../main/java/org/onap/aaf/cadi/filter/AUTHZ.java | 37 +++ .../org/onap/aaf/cadi/filter/AUTHZServlet.java | 100 +++++++ .../org/onap/aaf/cadi/filter/AccessGetter.java | 37 +++ .../java/org/onap/aaf/cadi/filter/CadiAccess.java | 243 ++++++++++++++++ .../java/org/onap/aaf/cadi/filter/CadiFilter.java | 305 +++++++++++++++++++++ .../org/onap/aaf/cadi/filter/CadiHTTPManip.java | 227 +++++++++++++++ .../main/java/org/onap/aaf/cadi/filter/FCGet.java | 77 ++++++ .../org/onap/aaf/cadi/filter/MapPermConverter.java | 55 ++++ .../onap/aaf/cadi/filter/NullPermConverter.java | 43 +++ .../java/org/onap/aaf/cadi/filter/PathFilter.java | 183 +++++++++++++ .../org/onap/aaf/cadi/filter/PermConverter.java | 32 +++ .../org/onap/aaf/cadi/filter/RolesAllowed.java | 55 ++++ .../java/org/onap/aaf/cadi/filter/ServletImpl.java | 55 ++++ 13 files changed, 1449 insertions(+) create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/AUTHZ.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/CadiAccess.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java (limited to 'core/src/main/java/org/onap/aaf/cadi/filter') diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZ.java b/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZ.java new file mode 100644 index 0000000..49a1634 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZ.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.servlet.Servlet; + +@Target({TYPE}) +@Retention(RUNTIME) +public @interface AUTHZ { + Class value(); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java b/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java new file mode 100644 index 0000000..871dee3 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.io.IOException; + +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * + */ +public class AUTHZServlet implements Servlet { + private String[] roles; + private Servlet delegate; + + protected AUTHZServlet(Class cls) { + try { + delegate = cls.newInstance(); + } catch (Exception e) { + delegate = null; + } + RolesAllowed rolesAllowed = cls.getAnnotation(RolesAllowed.class); + if(rolesAllowed == null) { + roles = null; + } else { + roles = rolesAllowed.value(); + } + } + + public void init(ServletConfig sc) throws ServletException { + if(delegate == null) throw new ServletException("Invalid Servlet Delegate"); + delegate.init(sc); + } + + public ServletConfig getServletConfig() { + return delegate.getServletConfig(); + } + + public String getServletInfo() { + return delegate.getServletInfo(); + } + + public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException { + if(roles==null) { + delegate.service(req,resp); + } else { // Validate + try { + HttpServletRequest hreq = (HttpServletRequest)req; + boolean proceed = false; + for(String role : roles) { + if(hreq.isUserInRole(role)) { + proceed = true; + break; + } + } + if(proceed) { + delegate.service(req,resp); + } else { + //baseRequest.getServletContext().log(hreq.getUserPrincipal().getName()+" Refused " + roles); + ((HttpServletResponse)resp).sendError(403); // forbidden + } + } catch(ClassCastException e) { + throw new ServletException("JASPIServlet only supports HTTPServletRequest/HttpServletResponse"); + } + } + } + + public void destroy() { + delegate.destroy(); + } + + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java b/core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java new file mode 100644 index 0000000..596afd2 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.config.Get; + +public class AccessGetter implements Get { + private final Access access; + public AccessGetter(Access access) { + this.access = access; + } + public String get(String name, String def, boolean print) { + return access.getProperty(name, def); + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/CadiAccess.java b/core/src/main/java/org/onap/aaf/cadi/filter/CadiAccess.java new file mode 100644 index 0000000..2ccd29a --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/CadiAccess.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +import javax.servlet.ServletContext; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.Get; + +public class CadiAccess implements Access { + // constants for a couple of very commonly used strings. + protected static final String FROM = "from"; + protected static final String FOR = "for"; + + // Properties derived from sources (could be property files, Valve Configurations, Filter + // configs, etc. + protected Properties props; + + // Will we write Logs? + protected Level willWrite = Level.INFO; + + protected ServletContext context; + protected Get getter = Get.NULL; // replace with Derived Class getter + private Symm symm; + + public CadiAccess(Map map) { + if(map!=null && !map.isEmpty()) { + props = new Properties(); + for(Entry es : map.entrySet()) { + Object v = es.getValue(); + if(v!=null) { + props.put(es.getKey(), v.toString()); + } + } + Object keyfile = props.get(Config.CADI_KEYFILE); + if(keyfile!=null) { + try { + FileInputStream fis = new FileInputStream(keyfile.toString()); + symm = Symm.obtain(fis); + } catch (Exception e) { + } + } + + } + } + + public Level willWrite() { + return willWrite; + } + + /* (non-Javadoc) + * @see com.att.cadi.Access#willLog(com.att.cadi.Access.Level) + */ + @Override + public boolean willLog(Level level) { + return willWrite.compareTo(level)<=0; + } + + /** + * Add the "Level" to the Buildline for Logging types that don't specify, or straight Streams, etc. Then buildline + * + * Build a line of code onto a StringBuilder based on Objects. Analyze whether + * spaces need including. + * + * @param level + * @param sb + * @param elements + * @return + */ + public final static StringBuilder buildLine(Level level, StringBuilder sb, Object[] elements) { + sb.append(level.name()); + return buildLine(sb,elements); + } + + /* + * Build a line of code onto a StringBuilder based on Objects. Analyze whether + * spaces need including. + * + * @param sb + * @param elements + * @return + */ + public final static StringBuilder buildLine(StringBuilder sb, Object[] elements) { + sb.append(' '); + String str; + boolean notFirst = false; + for(Object o : elements) { + if(o!=null) { + str = o.toString(); + + if(str.length()>0) { + if(notFirst && shouldAddSpace(str,true) && shouldAddSpace(sb,false)) { + sb.append(' '); + } else { + notFirst=true; + } + sb.append(str); + } + } + } + return sb; + } + + private static boolean shouldAddSpace(CharSequence c,boolean start) { + if(c.length()>0) + switch(c.charAt(start?0:c.length()-1)) { + case ' ': + case '\t': + case '\n': + case '\'': + case '"': + case '|': + return false; + } + return true; + } + + /** + * Standard mechanism for logging, given being within a Servlet Context + * + * Here, we treat + * + * if context exists, log to it, otherwise log to Std Out (The latter is usually for startup + * scenarios) + * + */ + public void log(Level level, Object... elements) { + if(willWrite.compareTo(level)<=0) { + StringBuilder sb = buildLine(level, new StringBuilder(),elements); + if(context==null) { + System.out.println(sb.toString()); + } else { + context.log(sb.toString()); + } + } + } + + /** + * Standard mechanism for logging an Exception, given being within a Servlet Context, etc + * + * if context exists, log to it, otherwise log to Std Out (The latter is usually for startup + * scenarios) + * + */ + public void log(Exception e, Object... elements) { + if(willWrite.compareTo(Level.ERROR)<=0) { + StringBuilder sb = buildLine(Level.ERROR, new StringBuilder(),elements); + + if(context==null) { + sb.append(e.toString()); + System.out.println(sb.toString()); + } else { + context.log(sb.toString(),e); + } + } + } + + public void setLogLevel(Level level) { + willWrite = level; + } + + /** + * Pass back the classloader of the Servlet Context, if it exists. Otherwise, get the classloader + * of this object. + */ + public ClassLoader classLoader() { // Use the Classloader that Context was created with + return (context==null?this:context).getClass().getClassLoader(); + } + + /** + * Get the Property from Context + */ + public String getProperty(String string, String def) { + String rv = null; + + if ( props != null ) + rv = props.getProperty( string, def ); + + if(rv==null) { + rv = context.getInitParameter(string); + } + return rv==null?def:rv; + + } + + public void load(InputStream is) throws IOException { + if(this.props==null) { + this.props = new Properties(); + } + this.props.load(is); + symm = Symm.obtain(this); + } + + public String decrypt(String encrypted, boolean anytext) throws IOException { + if(symm==null) { + String keyfile = getter.get(Config.CADI_KEYFILE, null, true); + if(keyfile!=null) { + FileInputStream fis = new FileInputStream(keyfile); + symm=Symm.obtain(fis); + fis.close(); + } + } + return (symm!=null && encrypted!=null && (anytext || encrypted.startsWith(Symm.ENC))) + ? symm.depass(encrypted) + : encrypted; + } + + @Override + public void printf(Level level, String fmt, Object[] elements) { + // TODO Auto-generated method stub + + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java b/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java new file mode 100644 index 0000000..0b8bb8f --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java @@ -0,0 +1,305 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +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 javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.CadiWrap; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.ServletContextAccess; +import org.onap.aaf.cadi.TrustChecker; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.Get; +import org.onap.aaf.cadi.taf.TafResp; +import org.onap.aaf.cadi.taf.TafResp.RESP; + +/** + * CadiFilter + * + * This class implements Servlet Filter, and ties together CADI implementations + * + * This class can be used in a standard J2EE Servlet manner. Optimal usage is for POJO operations, where + * one can enforce this Filter being first and primary. Depending on the Container, it + * may be more effective, in some cases, to utilize features that allow earlier determination of + * AUTHN (Authorization). An example would be "Tomcat Valve". These implementations, however, should + * be modeled after the "init" and "doFilter" functions, and be kept up to date as this class changes. + * + * + * + */ +public class CadiFilter implements Filter { + private static CadiHTTPManip httpChecker; + private static String[] pathExceptions; + private static List mapPairs; + private Access access; + private Object[] additionalTafLurs; + private static int count=0; + + public Lur getLur() { + return httpChecker.getLur(); + } + + /** + * Construct a viable Filter + * + * Due to the vagaries of many containers, there is a tendency to create Objects and call "Init" on + * them at a later time. Therefore, this object creates with an object that denies all access + * until appropriate Init happens, just in case the container lets something slip by in the meantime. + * + */ + public CadiFilter() { + additionalTafLurs = CadiHTTPManip.noAdditional; + } + + /** + * This constructor to be used when directly constructing and placing in HTTP Engine + * + * @param access + * @param moreTafLurs + * @throws ServletException + */ + public CadiFilter(Access access, Object ... moreTafLurs) throws ServletException { + additionalTafLurs = moreTafLurs; + init(new AccessGetter(this.access = access)); + } + + + /** + * Use this to pass in a PreContructed CADI Filter, but with initializing... let Servlet do it + * @param init + * @param access + * @param moreTafLurs + * @throws ServletException + */ + public CadiFilter(boolean init, PropAccess access, Object ... moreTafLurs) throws ServletException { + this.access = access; + if(init) { + init(new AccessGetter(access)); + } + additionalTafLurs = moreTafLurs; + } + + /** + * Init + * + * Standard Filter "init" call with FilterConfig to obtain properties. POJOs can construct a + * FilterConfig with the mechanism of their choice, and standard J2EE Servlet engines utilize this + * mechanism already. + */ + //TODO Always validate changes against Tomcat AbsCadiValve and Jaspi CadiSAM Init functions + public void init(FilterConfig filterConfig) throws ServletException { + // need the Context for Logging, instantiating ClassLoader, etc + ServletContextAccess sca=new ServletContextAccess(filterConfig); + if(access==null) { + access = sca; + } + + // Set Protected getter with base Access, for internal class instantiations + init(new FCGet(access, sca.context(), filterConfig)); + } + + + private void init(Get getter) throws ServletException { + // Start with the assumption of "Don't trust anyone". + TrustChecker tc = TrustChecker.NOTRUST; // default position + try { + @SuppressWarnings("unchecked") + Class ctc = (Class) Class.forName("com.att.cadi.aaf.v2_0.AAFTrustChecker"); + if(ctc!=null) { + Constructor contc = ctc.getConstructor(Access.class); + if(contc!=null) { + tc = contc.newInstance(access); + } + } + } catch (Exception e) { + access.log(Level.INIT, "AAFTrustChecker cannot be loaded",e.getMessage()); + } + + + // Synchronize, because some instantiations call init several times on the same object + // In this case, the epiTaf will be changed to a non-NullTaf, and thus not instantiate twice. + synchronized(CadiHTTPManip.noAdditional /*will always remain same Object*/) { + ++count; + if(httpChecker == null) { + if(access==null) { + access = new PropAccess(); + } + try { + httpChecker = new CadiHTTPManip(access,null /*reuseable Con*/,tc, additionalTafLurs); + } catch (CadiException e1) { + throw new ServletException(e1); + } + } else if(access==null) { + access= httpChecker.getAccess(); + } + + /* + * Setup Authn Path Exceptions + */ + if(pathExceptions==null) { + String str = getter.get(Config.CADI_NOAUTHN, null, true); + if(str!=null) { + pathExceptions = str.split("\\s*:\\s*"); + } + } + + /* + * SETUP Permission Converters... those that can take Strings from a Vendor Product, and convert to appropriate AAF Permissions + */ + if(mapPairs==null) { + String str = getter.get(Config.AAF_PERM_MAP, null, true); + if(str!=null) { + String mstr = getter.get(Config.AAF_PERM_MAP, null, true); + if(mstr!=null) { + String map[] = mstr.split("\\s*:\\s*"); + if(map.length>0) { + MapPermConverter mpc=null; + int idx; + mapPairs = new ArrayList(); + for(String entry : map) { + if((idx=entry.indexOf('='))<0) { // it's a Path, so create a new converter + access.log(Level.INIT,"Loading Perm Conversions for:",entry); + mapPairs.add(new Pair(entry,mpc=new MapPermConverter())); + } else { + if(mpc!=null) { + mpc.map().put(entry.substring(0,idx),entry.substring(idx+1)); + } else { + access.log(Level.ERROR,"cadi_perm_map is malformed; ",entry, "is skipped"); + } + } + } + } + } + } + } + } + + // Remove Getter + getter = Get.NULL; + } + + /** + * Containers call "destroy" when time to cleanup + */ + public void destroy() { + // Synchronize, in case multiCadiFilters are used. + synchronized(CadiHTTPManip.noAdditional) { + if(--count<=0 && httpChecker!=null) { + httpChecker.destroy(); + httpChecker=null; + access=null; + pathExceptions=null; + } + } + } + + /** + * doFilter + * + * This is the standard J2EE invocation. Analyze the request, modify response as necessary, and + * only call the next item in the filterChain if request is suitably Authenticated. + */ + //TODO Always validate changes against Tomcat AbsCadiValve and Jaspi CadiSAM functions + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + try { + HttpServletRequest hreq = (HttpServletRequest)request; + if(noAuthn(hreq)) { + chain.doFilter(request, response); + } else { + HttpServletResponse hresp = (HttpServletResponse)response; + TafResp tresp = httpChecker.validate(hreq, hresp); + if(tresp.isAuthenticated()==RESP.IS_AUTHENTICATED) { + CadiWrap cw = new CadiWrap(hreq, tresp, httpChecker.getLur(),getConverter(hreq)); + if(httpChecker.notCadi(cw, hresp)) { + chain.doFilter(cw,response); + } + } + } + } catch (ClassCastException e) { + throw new ServletException("CadiFilter expects Servlet to be an HTTP Servlet",e); + } + } + + + /** + * If PathExceptions exist, report if these should not have Authn applied. + * @param hreq + * @return + */ + private boolean noAuthn(HttpServletRequest hreq) { + if(pathExceptions!=null) { + String pi = hreq.getPathInfo(); + if(pi==null) return false; // JBoss sometimes leaves null + for(String pe : pathExceptions) { + if(pi.startsWith(pe))return true; + } + } + return false; + } + + /** + * Get Converter by Path + */ + private PermConverter getConverter(HttpServletRequest hreq) { + if(mapPairs!=null) { + String pi = hreq.getPathInfo(); + if(pi!=null) { + for(Pair p: mapPairs) { + if(pi.startsWith(p.name))return p.pc; + } + } + } + return NullPermConverter.singleton(); + } + + /** + * store PermConverters by Path prefix + * + */ + private class Pair { + public Pair(String key, PermConverter pc) { + name = key; + this.pc = pc; + } + public String name; + public PermConverter pc; + } + +} + diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java b/core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java new file mode 100644 index 0000000..a3df1c0 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.CadiWrap; +import org.onap.aaf.cadi.Connector; +import org.onap.aaf.cadi.CredVal; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.Taf; +import org.onap.aaf.cadi.TrustChecker; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.lur.EpiLur; +import org.onap.aaf.cadi.taf.HttpTaf; +import org.onap.aaf.cadi.taf.TafResp; +import org.onap.aaf.cadi.util.UserChainManip; + +/** + * Encapsulate common HTTP Manipulation Behavior. It will appropriately set + * HTTPServletResponse for Redirect or Forbidden, as needed. + * + * Further, this is useful, because it avoids multiple creates of Connections, where some Filters + * are created and destroyed regularly. + * + * + * + */ +public class CadiHTTPManip { + private static final String ACCESS_CADI_CONTROL = ".access|cadi|control"; + private static final String METH = "OPTIONS"; + private static final String CADI = "/cadi/"; + private static final String CADI_CACHE_PRINT = "/cadi/cache/print"; + private static final String CADI_CACHE_CLEAR = "/cadi/cache/clear"; + private static final String CADI_LOG_SET = "/cadi/log/set/"; + private Access access; + private HttpTaf taf; + private CredVal up; + private Lur lur; + private String thisPerm,companyPerm,aaf_id; + + public static final Object[] noAdditional = new Object[0]; // CadiFilter can be created each call in some systems + + + public CadiHTTPManip(Access access, Connector con, TrustChecker tc, Object ... additionalTafLurs) throws CadiException { + synchronized(CADI) { + this.access = access; +// Get getter = new AccessGetter(access); + Config.setDefaultRealm(access); + + aaf_id = access.getProperty(Config.CADI_ALIAS,access.getProperty(Config.AAF_MECHID, null)); + if(aaf_id==null) { + access.printf(Level.INIT, "%s is not set. %s can be used instead",Config.AAF_MECHID,Config.CADI_ALIAS); + } else { + access.printf(Level.INIT, "%s is set to %s",Config.AAF_MECHID,aaf_id); + } + String ns = aaf_id==null?null:UserChainManip.idToNS(aaf_id); + if(ns!=null) { + thisPerm = ns+ACCESS_CADI_CONTROL; + int dot = ns.indexOf('.'); + if(dot>=0) { + int dot2=ns.indexOf('.',dot+1); + if(dot2<0) { + dot2=dot; + } + companyPerm = ns.substring(0, dot2)+ACCESS_CADI_CONTROL; + } else { + companyPerm = "com"+ACCESS_CADI_CONTROL; + } + } else { + thisPerm = companyPerm = "com"+ACCESS_CADI_CONTROL; + } + + if(con!=null) { // try to reutilize connector + List ll = null; + for(Object tl : additionalTafLurs) { + if(tl instanceof Lur) { + if(ll==null) { + ll = new ArrayList(); + ll.add(con.newLur()); + } + ll.add((Lur)tl); + } + } + if(ll==null) { + lur = con.newLur(); + } else { + lur = new EpiLur((Lur[])ll.toArray()); + } + } else { + lur = Config.configLur(access, additionalTafLurs); + } + tc.setLur(lur); + if(lur instanceof EpiLur) { + up = ((EpiLur)lur).getUserPassImpl(); + } else if(lur instanceof CredVal) { + up = (CredVal)lur; + } else { + up = null; + } + taf = Config.configHttpTaf(access, tc, up, lur, additionalTafLurs); + } + } + + public TafResp validate(HttpServletRequest hreq, HttpServletResponse hresp) throws IOException { + TafResp tresp = taf.validate(Taf.LifeForm.LFN, hreq, hresp); + switch(tresp.isAuthenticated()) { + case IS_AUTHENTICATED: + access.printf(Level.INFO,"Authenticated: %s from %s:%d" + , tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort()); + break; + case TRY_AUTHENTICATING: + switch (tresp.authenticate()) { + case IS_AUTHENTICATED: + access.printf(Level.INFO,"Authenticated: %s from %s:%d" + , tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort()); + break; + case HTTP_REDIRECT_INVOKED: + access.log(Level.INFO,"Authenticating via redirection: ", tresp.desc()); + break; + case NO_FURTHER_PROCESSING: + access.printf(Level.AUDIT,"Authentication Failure: %s from %s:%d" + , tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort()); + hresp.sendError(403, tresp.desc()); // Forbidden + break; + + default: + access.printf(Level.AUDIT,"No TAF will authorize for request from %s:%d" + , hreq.getRemoteAddr(), hreq.getRemotePort()); + hresp.sendError(403, tresp.desc()); // Forbidden + } + break; + case NO_FURTHER_PROCESSING: + access.printf(Level.AUDIT,"Authentication Failure: %s from %s:%d", + tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort()); + hresp.sendError(403, "Access Denied"); // FORBIDDEN + break; + default: + access.printf(Level.AUDIT,"No TAF will authorize for request from %s:%d" + , hreq.getRemoteAddr(), hreq.getRemotePort()); + hresp.sendError(403, "Access Denied"); // FORBIDDEN + } + return tresp; + } + + public boolean notCadi(CadiWrap req, HttpServletResponse resp) { + + String pathInfo = req.getPathInfo(); + if(METH.equalsIgnoreCase(req.getMethod()) && pathInfo!=null && pathInfo.contains(CADI)) { + if(req.getUser().equals(aaf_id) || req.isUserInRole(thisPerm) || req.isUserInRole(companyPerm)) { + try { + if(pathInfo.contains(CADI_CACHE_PRINT)) { + resp.getOutputStream().println(lur.toString()); + resp.setStatus(200); + return false; + } else if(pathInfo.contains(CADI_CACHE_CLEAR)) { + StringBuilder report = new StringBuilder(); + lur.clear(req.getUserPrincipal(), report); + resp.getOutputStream().println(report.toString()); + resp.setStatus(200); + return false; + } else if(pathInfo.contains(CADI_LOG_SET)) { + Level l; + int slash = pathInfo.lastIndexOf('/'); + String level = pathInfo.substring(slash+1); + try { + l = Level.valueOf(level); + access.printf(Level.AUDIT, "%s has set CADI Log Level to '%s'",req.getUser(),l.name()); + access.setLogLevel(l); + } catch (IllegalArgumentException e) { + access.printf(Level.AUDIT, "'%s' is not a valid CADI Log Level",level); + } + return false; + } + } catch (IOException e) { + access.log(e); + } + } + } + return true; + } + + public Lur getLur() { + return lur; + } + + public void destroy() { + access.log(Level.INFO,"CadiHttpChecker destroyed."); + if(lur!=null) { + lur.destroy(); + lur=null; + } + } + + public Access getAccess() { + return access; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java b/core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java new file mode 100644 index 0000000..e6912e7 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Get; + +/* + * A private method to query the Filter config and if not exists, return the default. This + * cleans up the initialization code. + */ +class FCGet implements Get { + /** + * + */ + private final Access access; + private FilterConfig filterConfig; + private ServletContext context; + + public FCGet(Access access, ServletContext context, FilterConfig filterConfig) { + this.access = access; + this.context = context; + this.filterConfig = filterConfig; + } + + public String get(String name, String def, boolean print) { + String str = null; + // Try Server Context First + if(context!=null) { + str = context.getInitParameter(name); + } + + // Try Filter Context next + if(str==null && filterConfig != null) { + str = filterConfig.getInitParameter(name); + } + + if(str==null) { + str = access.getProperty(name, def); + } + // Take def if nothing else + if(str==null) { + str = def; + // don't log defaults + } else { + str = str.trim(); // this is vital in Property File based values, as spaces can hide easily + if(print) { + access.log(Level.INFO,"Setting", name, "to", str); + } + } + return str; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java b/core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java new file mode 100644 index 0000000..933e6f9 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.util.HashMap; +import java.util.Map; + +public class MapPermConverter implements PermConverter { + private HashMap map; + + /** + * Create with colon separated name value pairs + * i.e. teAdmin=com.att.myNS.myPerm|*|*:teUser=... + * + * @param value + */ + public MapPermConverter() { + map = new HashMap(); + } + + /** + * use to instantiate entries + * + * @return + */ + public Map map() { + return map; + } + + public String convert(String minimal) { + String rv = map.get(minimal); + return rv==null?minimal:rv; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java b/core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java new file mode 100644 index 0000000..223e1a4 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + + +/** + * A NullPermConverter + * + * Obey the PermConverter Interface, but passed in "minimal" String is not converted. + * + * + */ +public class NullPermConverter implements PermConverter { + + private NullPermConverter() {} + private static final NullPermConverter singleton = new NullPermConverter(); + public static NullPermConverter singleton() {return singleton;} + + public String convert(String minimal) { + return minimal; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java b/core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java new file mode 100644 index 0000000..87e3c78 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Config; + +/** + * PathFilter + * + * This class implements Servlet Filter, and uses AAF to validate access to a Path. + * + * This class can be used in a standard J2EE Servlet manner. + * + * + */ +public class PathFilter implements Filter { + private ServletContext context; + private String aaf_type; + private String not_authorized_msg; + private final Log log; + + /** + * Construct a viable Filter for installing in Container WEB.XML, etc. + * + */ + public PathFilter() { + log = new Log() { + public void info(String ... msg) { + context.log(build("INFO:",msg)); + } + public void audit(String ... msg) { + context.log(build("AUDIT:",msg)); + } + private String build(String type, String []msg) { + StringBuilder sb = new StringBuilder(type); + for(String s : msg) { + sb.append(' '); + sb.append(s); + } + return sb.toString(); + } + + }; + } + + /** + * Filter that can be constructed within Java + * @param access + */ + public PathFilter(final Access access) { + log = new Log() { + public void info(String ... msg) { + access.log(Level.INFO, (Object[])msg); + } + public void audit(String ... msg) { + access.log(Level.AUDIT, (Object[])msg); + } + }; + } + + /** + * Init + * + * Standard Filter "init" call with FilterConfig to obtain properties. POJOs can construct a + * FilterConfig with the mechanism of their choice, and standard J2EE Servlet engines utilize this + * mechanism already. + */ + public void init(FilterConfig filterConfig) throws ServletException { + // need the Context for Logging, instantiating ClassLoader, etc + context = filterConfig.getServletContext(); + StringBuilder sb = new StringBuilder(); + StringBuilder err = new StringBuilder(); + Object attr = context.getAttribute(Config.PATHFILTER_NS); + if(attr==null) { + err.append("PathFilter - pathfilter_ns is not set"); + } else { + sb.append(attr.toString()); + } + + attr = context.getAttribute(Config.PATHFILTER_STACK); + if(attr==null) { + log.info("PathFilter - No pathfilter_stack set, ignoring"); + } else { + sb.append('.'); + sb.append(attr.toString()); + } + + attr = context.getAttribute(Config.PATHFILTER_URLPATTERN); + if(attr==null) { + log.info("PathFilter - No pathfilter_urlpattern set, defaulting to 'urlpattern'"); + sb.append(".urlpattern"); + } else { + sb.append('.'); + sb.append(attr.toString()); + } + + log.info("PathFilter - AAF Permission Type is",sb.toString()); + + sb.append('|'); + + aaf_type = sb.toString(); + + attr = context.getAttribute(Config.PATHFILTER_NOT_AUTHORIZED_MSG); + if(attr==null) { + not_authorized_msg = "Forbidden - Not Authorized to access this Path"; + } else { + not_authorized_msg = attr.toString(); + } + + if(err.length()>0) { + throw new ServletException(err.toString()); + } + } + + private interface Log { + public void info(String ... msg); + public void audit(String ... msg); + } + + /** + * doFilter + * + * This is the standard J2EE invocation. Analyze the request, modify response as necessary, and + * only call the next item in the filterChain if request is suitably Authenticated. + */ + //TODO Always validate changes against Tomcat AbsCadiValve and Jaspi CadiSAM functions + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest hreq = (HttpServletRequest)request; + HttpServletResponse hresp = (HttpServletResponse)response; + String perm = aaf_type+hreq.getPathInfo()+'|'+hreq.getMethod(); + if(hreq.isUserInRole(perm)) { + chain.doFilter(request, response); + } else { + log.audit("PathFilter has denied",hreq.getUserPrincipal().getName(),"access to",perm); + hresp.sendError(403,not_authorized_msg); + } + } + + /** + * Containers call "destroy" when time to cleanup + */ + public void destroy() { + log.info("PathFilter destroyed."); + } + + + +} + diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java b/core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java new file mode 100644 index 0000000..8f71e29 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +/** + * Convert a simplistic, single string Permission into an Enterprise Scoped Perm + * + * + */ +public interface PermConverter { + public String convert(String minimal); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java b/core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java new file mode 100644 index 0000000..0a5873e --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +/** + * RolesAllowed + * + * + * Similar to Java EE's Spec from Annotations 1.1, 2.8 + * + * That Spec, however, was geared towards being able to route calls to Methods on Objects, and thus needed a more refined + * sense of permissions hierarchy. The same mechanism, however, can easily be achieved on single Servlet/Handlers in + * POJOs like Jetty by simply adding the Roles Allowed in a similar Annotation + * + */ +package org.onap.aaf.cadi.filter; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * JASPI Style Annotation of RolesAllowed when the coding style is desired but actually including all + * JEE jars is not. If using actual JASPI, use official @interface classes, not this one... + * + */ +@Target({TYPE}) +@Retention(RUNTIME) +public @interface RolesAllowed { + /** + * Security role of the implementation, which doesn't have to be an EJB or CORBA like object. Can be just a + * Handler + * @return + */ + String[] value(); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java b/core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java new file mode 100644 index 0000000..f581c5f --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 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==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +/** + * RolesAllowed + * + * + * Similar to Java EE's Spec from Annotations 1.1, 2.8 + * + * That Spec, however, was geared towards being able to route calls to Methods on Objects, and thus needed a more refined + * sense of permissions hierarchy. The same mechanism, however, can easily be achieved on single Servlet/Handlers in + * POJOs like Jetty by simply adding the Roles Allowed in a similar Annotation + * + */ +package org.onap.aaf.cadi.filter; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.servlet.Servlet; + +/** + * + */ +@Target({TYPE}) +@Retention(RUNTIME) +public @interface ServletImpl { + /** + * Security role of the implementation, which doesn't have to be an EJB or CORBA like object. Can be just a + * Handler + * @return + */ + Class value(); +} -- cgit 1.2.3-korg