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.Logger;
34 import org.apache.log4j.PropertyConfigurator;
35 import org.apache.shiro.authc.AuthenticationException;
36 import org.apache.shiro.authc.AuthenticationInfo;
37 import org.apache.shiro.authc.AuthenticationToken;
38 import org.apache.shiro.authc.UsernamePasswordToken;
39 import org.apache.shiro.realm.AuthorizingRealm;
40 import org.apache.shiro.subject.PrincipalCollection;
41 import org.onap.aaf.cadi.Access.Level;
42 import org.onap.aaf.cadi.CadiException;
43 import org.onap.aaf.cadi.LocatorException;
44 import org.onap.aaf.cadi.Permission;
45 import org.onap.aaf.cadi.PropAccess;
46 import org.onap.aaf.cadi.Symm;
47 import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn;
48 import org.onap.aaf.cadi.aaf.v2_0.AAFCon;
49 import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm;
50 import org.onap.aaf.cadi.config.Config;
51 import org.onap.aaf.cadi.filter.MapBathConverter;
52 import org.onap.aaf.cadi.util.CSV;
53 import org.onap.aaf.misc.env.APIException;
54 public class AAFRealm extends AuthorizingRealm {
56 final static Logger logger = Logger.getLogger(AAFRealm.class);
58 public static final String AAF_REALM = "AAFRealm";
60 private PropAccess access;
61 private AAFCon<?> acon;
62 private AAFAuthn<?> authn;
63 private HashSet<Class<? extends AuthenticationToken>> supports;
64 private AAFLurPerm authz;
65 private MapBathConverter mbc;
66 private Map<String,String> idMap;
71 * There appears to be no configuration objects or references available for CADI to start with.
75 access = new PropAccess(); // pick up cadi_prop_files from VM_Args
78 String cadi_prop_files = access.getProperty(Config.CADI_PROP_FILES);
79 if(cadi_prop_files==null) {
80 String msg = Config.CADI_PROP_FILES + " in VM Args is required to initialize AAFRealm.";
81 access.log(Level.INIT,msg);
82 throw new RuntimeException(msg);
85 String log4jConfigFile = "./etc/org.onap.cadi.logging.cfg";
86 PropertyConfigurator.configure(log4jConfigFile);
87 System.setOut(createLoggingProxy(System.out));
88 System.setErr(createLoggingProxy(System.err));
89 } catch(Exception e) {
92 //System.out.println("Configuration done");
94 acon = AAFCon.newInstance(access);
95 authn = acon.newAuthn();
96 authz = acon.newLur(authn);
98 final String csv = access.getProperty(Config.CADI_BATH_CONVERT);
101 mbc = new MapBathConverter(access, new CSV(csv));
102 logger.info("MapBathConversion enabled with file "+csv);
103 idMap = new TreeMap<String,String>();
105 for(Entry<String, String> es : mbc.map().entrySet()) {
106 String oldID = es.getKey();
107 if(oldID.startsWith("Basic ")) {
108 oldID = Symm.base64noSplit.decode(oldID.substring(6));
109 int idx = oldID.indexOf(':');
111 oldID = oldID.substring(0, idx);
114 String newID = es.getValue();
115 if(newID.startsWith("Basic ")) {
116 newID = Symm.base64noSplit.decode(newID.substring(6));
117 int idx = newID.indexOf(':');
119 newID = newID.substring(0, idx);
122 idMap.put(oldID,newID);
124 } catch (IOException e) {
125 logger.error(e.getMessage(), e);
128 } catch (APIException | CadiException | LocatorException e) {
129 String msg = "Cannot initiate AAFRealm";
130 logger.info(msg + " "+ e.getMessage(), e);
131 throw new RuntimeException(msg,e);
134 supports = new HashSet<Class<? extends AuthenticationToken>>();
135 supports.add(UsernamePasswordToken.class);
137 public static PrintStream createLoggingProxy(final PrintStream realPrintStream) {
138 return new PrintStream(realPrintStream) {
139 public void print(final String string) {
140 realPrintStream.print(string);
147 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
148 logger.debug("AAFRealm.doGetAuthenticationInfo :"+token);
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;
157 final String oldBath = "Basic " + Symm.base64noSplit.encode(user+':'+password);
158 String bath = mbc.convert(access, oldBath);
160 bath = Symm.base64noSplit.decode(bath.substring(6));
161 int colon = bath.indexOf(':');
163 authUser = bath.substring(0, colon);
164 authPassword = bath.substring(colon+1);
167 } catch (IOException e) {
168 logger.error(e.getMessage(), e);
173 err = authn.validate(authUser,authPassword);
174 } catch (IOException e) {
175 err = "Credential cannot be validated";
176 logger.error(err, e);
181 throw new AuthenticationException(err);
184 return new AAFAuthenticationInfo(
192 protected void assertCredentialsMatch(AuthenticationToken atoken, AuthenticationInfo ai)throws AuthenticationException {
193 if(ai instanceof AAFAuthenticationInfo) {
194 if(!((AAFAuthenticationInfo)ai).matches(atoken)) {
195 throw new AuthenticationException("Credentials do not match");
198 throw new AuthenticationException("AuthenticationInfo is not an AAFAuthenticationInfo");
204 protected AAFAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
205 logger.debug("AAFRealm.doGetAuthenthorizationInfo");
206 Principal bait = (Principal)principals.getPrimaryPrincipal();
207 Principal newBait = bait;
209 final String newID = idMap.get(bait.getName());
211 newBait = new Principal() {
213 public String getName() {
219 List<Permission> pond = new ArrayList<>();
220 authz.fishAll(newBait,pond);
222 return new AAFAuthorizationInfo(access,bait,pond);
227 public boolean supports(AuthenticationToken token) {
228 return supports.contains(token.getClass());
232 public String getName() {