2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
22 package org.onap.aaf.cadi.aaf.v2_0;
24 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.List;
29 import org.onap.aaf.cadi.AbsUserCache;
30 import org.onap.aaf.cadi.Access;
31 import org.onap.aaf.cadi.CachedPrincipal;
32 import org.onap.aaf.cadi.CadiException;
33 import org.onap.aaf.cadi.User;
34 import org.onap.aaf.cadi.aaf.AAFPermission;
35 import org.onap.aaf.cadi.client.Future;
36 import org.onap.aaf.cadi.client.Rcli;
37 import org.onap.aaf.cadi.locator.SingleEndpointLocator;
38 import org.onap.aaf.cadi.lur.ConfigPrincipal;
40 import aaf.v2_0.CredRequest;
42 public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> {
43 private AAFCon<CLIENT> con;
47 * Configure with Standard AAF properties, Stand alone
49 * @throws Exception ..
52 AAFAuthn(AAFCon<CLIENT> con) {
53 super(con.access,con.cleanInterval,con.highCount,con.usageRefreshTriggerCount);
58 * Configure with Standard AAF properties, but share the Cache (with AAF Lur)
63 AAFAuthn(AAFCon<CLIENT> con, AbsUserCache<AAFPermission> cache) {
69 * Return Native Realm of AAF Instance.
73 public String getRealm() {
78 * Returns null if ok, or an Error String;
80 * Convenience function. Passes "null" for State object
82 public String validate(String user, String password) throws IOException {
83 return validate(user,password,null);
87 * Returns null if ok, or an Error String;
89 * For State Object, you may put in HTTPServletRequest or AuthzTrans, if available. Otherwise,
96 * @throws CadiException
99 public String validate(String user, String password, Object state) throws IOException {
100 password = access.decrypt(password, false);
101 byte[] bytes = password.getBytes();
102 User<AAFPermission> usr = getUser(user,bytes);
104 if (usr != null && !usr.permExpired()) {
105 if (usr.principal==null) {
106 return "User already denied";
112 AAFCachedPrincipal cp = new AAFCachedPrincipal(user, bytes, con.userExpires);
113 // Since I've relocated the Validation piece in the Principal, just revalidate, then do Switch
115 switch(cp.revalidate(state)) {
120 addUser(new User<AAFPermission>(cp,con.userExpires));
124 return "AAF Inaccessible";
126 addUser(new User<AAFPermission>(user,bytes,con.userExpires));
127 return "user/pass combo invalid for " + user;
129 return "AAF denies API for " + user;
131 return "AAFAuthn doesn't handle Principal " + user;
135 private class AAFCachedPrincipal extends ConfigPrincipal implements CachedPrincipal {
136 private long expires;
137 private long timeToLive;
139 private AAFCachedPrincipal(String name, byte[] pass, int timeToLive) {
141 this.timeToLive = timeToLive;
142 expires = timeToLive + System.currentTimeMillis();
145 public Resp revalidate(Object state) {
147 try { // these SHOULD be an AAFConHttp and a AAFLocator or SingleEndpointLocator objects, but put in a try to be safe
148 AAFConHttp forceCastCon = (AAFConHttp) con;
149 if (forceCastCon.hman().loc instanceof SingleEndpointLocator) {
150 maxRetries = 1; // we cannot retry the single LGW gateway!
152 AAFLocator forceCastLoc = (AAFLocator) forceCastCon.hman().loc;
153 maxRetries = forceCastLoc.maxIters();
155 } catch (Exception e) {
156 access.log(Access.Level.DEBUG, e);
158 List<URI> attemptedUris = new ArrayList<>();
160 for (int retries = 0;; retries++) {
162 Miss missed = missed(getName(), getCred());
163 if (missed == null || missed.mayContinue()) {
164 CredRequest cr = new CredRequest();
166 cr.setPassword(new String(getCred()));
167 Rcli<CLIENT> client = con.clientIgnoreAlreadyAttempted(attemptedUris);
168 thisUri = client.getURI();
169 Future<String> fp = client.readPost("/authn/validate", con.credReqDF, cr);
170 //Rcli<CLIENT> client = con.client().forUser(con.basicAuth(getName(), new String(getCred())));
171 //Future<String> fp = client.read(
172 // "/authn/basicAuth",
175 if (fp.get(con.timeout)) {
176 expires = System.currentTimeMillis() + timeToLive;
177 addUser(new User<AAFPermission>(this, timeToLive));
178 return Resp.REVALIDATED;
180 addMiss(getName(), getCred());
181 return Resp.UNVALIDATED;
184 return Resp.UNVALIDATED;
186 } catch (Exception e) {
187 if (thisUri != null) {
188 attemptedUris.add(thisUri);
191 if (retries > maxRetries) {
192 return Resp.INACCESSIBLE;
198 public long expires() {