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 --- .../java/org/onap/aaf/cadi/taf/HttpEpiTaf.java | 185 +++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java (limited to 'core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java') diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java b/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java new file mode 100644 index 0000000..05832f7 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * ============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.taf; + +import java.net.URI; +import java.security.Principal; +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.CachedPrincipal; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.TrustChecker; +import org.onap.aaf.cadi.CachedPrincipal.Resp; +import org.onap.aaf.cadi.Taf.LifeForm; + +/** + * HttpEpiTaf + * + * An extension of the basic "EpiTAF" concept, check known HTTP Related TAFs for valid credentials + * + * + */ +public class HttpEpiTaf implements HttpTaf { + private HttpTaf[] tafs; + private Access access; + private Locator locator; + private TrustChecker trustChecker; + + /** + * HttpEpiTaf constructor + * + * Construct the HttpEpiTaf from variable Http specific TAF parameters + + * @param tafs + * @throws CadiException + */ + public HttpEpiTaf(Access access, Locator locator, TrustChecker tc, HttpTaf ... tafs) throws CadiException{ + this.tafs = tafs; + this.access = access; + this.locator = locator; + this.trustChecker = tc; + // Establish what Header Property to look for UserChain/Trust Props +// trustChainProp = access.getProperty(Config.CADI_TRUST_PROP, Config.CADI_TRUST_PROP_DEFAULT); + + if(tafs.length==0) throw new CadiException("Need at least one HttpTaf implementation in constructor"); + } + + /** + * validate + * + * Respond with the first Http specific TAF to authenticate user based on variable info + * and "LifeForm" (is it a human behind a browser, or a server utilizing HTTP Protocol). + * + * If there is no HttpTAF that can authenticate, respond with the first TAF that suggests it can + * establish an Authentication conversation (TRY_AUTHENTICATING) (Examples include a redirect to CSP + * Servers for CSP Cookie, or BasicAuth 401 response, suggesting User/Password for given Realm + * submission + * + * If no TAF declares either, respond with NullTafResp (which denies all questions) + */ + public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { + // Given a LifeForm Neutral, for HTTP, we need to discover true Life-Form Readings + if(reading==LifeForm.LFN) { + reading = tricorderScan(req); + } + TafResp tresp=null, firstTry = null; + List redirectables = null; + + for(HttpTaf taf : tafs) { + tresp = taf.validate(reading, req, resp); + switch(tresp.isAuthenticated()) { + case TRY_ANOTHER_TAF: + break; // and loop + case TRY_AUTHENTICATING: + if(tresp instanceof Redirectable) { + if(redirectables==null) { + redirectables = new ArrayList(); + } + redirectables.add((Redirectable)tresp); + } else if(firstTry==null) { + firstTry = tresp; + } + break; + case IS_AUTHENTICATED: + tresp = trustChecker.mayTrust(tresp, req); + return tresp; + default: + return tresp; + } + } + + // If No TAFs configured, at this point. It is safer at this point to be "not validated", + // rather than "let it go" + // Note: if exists, there will always be more than 0 entries, according to above code + if(redirectables==null) { + return firstTry!=null?firstTry:NullTafResp.singleton(); + } + + // If there is one Tryable entry then return it + if(redirectables.size()>1) { + return LoginPageTafResp.create(access,locator,resp,redirectables); + } else { + return redirectables.get(0); + } + } + + public boolean revalidate(Principal prin) throws Exception { + return false; + } + + /* + * Since this is internal, we use a little Star Trek humor to indicate looking in the HTTP Request to see if we can determine what kind + * of "LifeForm" reading we can determine, i.e. is there a Human (CarbonBasedLifeForm) behind a browser, or is it mechanical + * id (SiliconBasedLifeForm)? This makes a difference in some Authentication, i.e CSP, which doesn't work well for SBLFs + */ + private LifeForm tricorderScan(HttpServletRequest req) { + // For simplicity's sake, we'll say Humans use FQDNs, not IPs. + + String auth = req.getParameter("Authentication"); + if(auth!=null) { + if("BasicAuth".equals(auth)) { + return LifeForm.SBLF; + } + } + // Current guess that only Browsers bother to set "Agent" codes that identify the kind of browser they are. + // If mechanical frameworks are found that populate this, then more advanced analysis may be required + // 1/22/2013 + String agent = req.getHeader("User-Agent"); + if(agent!=null && agent.startsWith("Mozilla")) // covers I.E./Firefox/Safari/probably any other "advanced" Browser see http://en.wikipedia.org/wiki/User_agent + return LifeForm.CBLF; + return LifeForm.SBLF; // notably skips "curl","wget", (which is desired behavior. We don't want to try CSP, etc on these) + } + + public Resp revalidate(CachedPrincipal prin) { + Resp resp; + for(HttpTaf taf : tafs) { + resp = taf.revalidate(prin); + switch(resp) { + case NOT_MINE: + break; + default: + return resp; + } + } + return Resp.NOT_MINE; + } + + /** + * List HttpTafs with their "toString" representations... primarily useful for Debugging in an IDE + * like Eclipse. + */ + public String toString() { + StringBuilder sb = new StringBuilder(); + for(HttpTaf ht : tafs) { + sb.append(ht.toString()); + sb.append(". "); + } + return sb.toString(); + } +} -- cgit 1.2.3-korg