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====================================================
21 package org.onap.aaf.cadi.shiro;
23 import java.io.IOException;
24 import java.io.PrintStream;
25 import java.security.Principal;
26 import java.util.ArrayList;
27 import java.util.HashSet;
28 import java.util.List;
30 import java.util.Map.Entry;
31 import java.util.TreeMap;
33 import org.apache.log4j.PropertyConfigurator;
34 import org.apache.shiro.authc.AuthenticationException;
35 import org.apache.shiro.authc.AuthenticationInfo;
36 import org.apache.shiro.authc.AuthenticationToken;
37 import org.apache.shiro.authc.UsernamePasswordToken;
38 import org.apache.shiro.realm.AuthorizingRealm;
39 import org.apache.shiro.subject.PrincipalCollection;
40 import org.onap.aaf.cadi.Access.Level;
41 import org.onap.aaf.cadi.CadiException;
42 import org.onap.aaf.cadi.LocatorException;
43 import org.onap.aaf.cadi.Permission;
44 import org.onap.aaf.cadi.PropAccess;
45 import org.onap.aaf.cadi.Symm;
46 import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn;
47 import org.onap.aaf.cadi.aaf.v2_0.AAFCon;
48 import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm;
49 import org.onap.aaf.cadi.config.Config;
50 import org.onap.aaf.cadi.filter.MapBathConverter;
51 import org.onap.aaf.cadi.util.CSV;
52 import org.onap.aaf.misc.env.APIException;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 public class AAFRealm extends AuthorizingRealm {
58 final static Logger logger = LoggerFactory.getLogger(AAFRealm.class);
60 public static final String AAF_REALM = "AAFRealm";
62 private PropAccess access;
63 private AAFCon<?> acon;
64 private AAFAuthn<?> authn;
65 private HashSet<Class<? extends AuthenticationToken>> supports;
66 private AAFLurPerm authz;
67 private MapBathConverter mbc;
68 private Map<String,String> idMap;
73 * There appears to be no configuration objects or references available for CADI to start with.
77 access = new PropAccess(); // pick up cadi_prop_files from VM_Args
80 String cadi_prop_files = access.getProperty(Config.CADI_PROP_FILES);
81 if(cadi_prop_files==null) {
82 String msg = Config.CADI_PROP_FILES + " in VM Args is required to initialize AAFRealm.";
83 access.log(Level.DEBUG,msg);
84 throw new RuntimeException(msg);
87 String log4jConfigFile = "./etc/org.ops4j.pax.logging.cfg";
89 PropertyConfigurator.configure(log4jConfigFile);
90 System.setOut(createLoggingProxy(System.out));
91 System.setErr(createLoggingProxy(System.err));
92 } catch(Exception e) {
95 //System.out.println("Configuration done");
97 acon = AAFCon.newInstance(access);
98 authn = acon.newAuthn();
99 authz = acon.newLur(authn);
100 final String csv = access.getProperty(Config.CADI_BATH_CONVERT);
103 mbc = new MapBathConverter(access, new CSV(csv));
104 logger.info("MapBathConversion enabled with file "+csv);
105 idMap = new TreeMap<String,String>();
107 for(Entry<String, String> es : mbc.map().entrySet()) {
108 String oldID = es.getKey();
109 if(oldID.startsWith("Basic ")) {
110 oldID = Symm.base64noSplit.decode(oldID.substring(6));
111 int idx = oldID.indexOf(':');
113 oldID = oldID.substring(0, idx);
116 String newID = es.getValue();
117 if(newID.startsWith("Basic ")) {
118 newID = Symm.base64noSplit.decode(newID.substring(6));
119 int idx = newID.indexOf(':');
121 newID = newID.substring(0, idx);
124 idMap.put(oldID,newID);
126 } catch (IOException e) {
130 } catch (APIException | CadiException | LocatorException e) {
131 String msg = "Cannot initiate AAFRealm";
132 access.log(Level.INIT,msg,e.getMessage());
133 throw new RuntimeException(msg,e);
136 supports = new HashSet<Class<? extends AuthenticationToken>>();
137 supports.add(UsernamePasswordToken.class);
139 public static PrintStream createLoggingProxy(final PrintStream realPrintStream) {
140 return new PrintStream(realPrintStream) {
141 public void print(final String string) {
142 realPrintStream.print(string);
149 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
150 final UsernamePasswordToken upt = (UsernamePasswordToken)token;
151 final String user = upt.getUsername();
152 String authUser = user;
153 final String password=new String(upt.getPassword());
154 String authPassword = password;
158 final String oldBath = "Basic " + Symm.base64noSplit.encode(user+':'+password);
159 String bath = mbc.convert(access, oldBath);
161 bath = Symm.base64noSplit.decode(bath.substring(6));
162 int colon = bath.indexOf(':');
164 authUser = bath.substring(0, colon);
165 authPassword = bath.substring(colon+1);
166 access.log(Level.DEBUG, authUser,"user authenticated");
167 access.log(Level.DEBUG, authn.validate(authUser,authPassword));
170 } catch (IOException e) {
176 err = authn.validate(authUser,authPassword);
177 } catch (IOException e) {
178 err = "Credential cannot be validated";
179 access.log(Level.DEBUG, e, err);
183 access.log(Level.DEBUG, err, " - Credential cannot be validated");
184 throw new AuthenticationException(err);
187 return new AAFAuthenticationInfo(
197 protected void assertCredentialsMatch(AuthenticationToken atoken, AuthenticationInfo ai)throws AuthenticationException {
198 if(ai instanceof AAFAuthenticationInfo) {
199 if(!((AAFAuthenticationInfo)ai).matches(atoken)) {
200 throw new AuthenticationException("Credentials do not match");
203 throw new AuthenticationException("AuthenticationInfo is not an AAFAuthenticationInfo");
209 protected AAFAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
210 Principal bait = (Principal)principals.getPrimaryPrincipal();
211 Principal newBait = bait;
213 final String newID = idMap.get(bait.getName());
215 newBait = new Principal() {
217 public String getName() {
223 List<Permission> pond = new ArrayList<>();
224 authz.fishAll(newBait,pond);
225 return new AAFAuthorizationInfo(access,bait,pond);
230 public boolean supports(AuthenticationToken token) {
231 return supports.contains(token.getClass());
235 public String getName() {