2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.usermanager.internal;
11 import java.io.FileNotFoundException;
12 import java.io.IOException;
13 import java.io.ObjectInputStream;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.EnumSet;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.List;
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.ConcurrentMap;
25 import org.apache.commons.lang3.StringUtils;
26 import org.eclipse.osgi.framework.console.CommandInterpreter;
27 import org.eclipse.osgi.framework.console.CommandProvider;
28 import org.opendaylight.controller.clustering.services.CacheConfigException;
29 import org.opendaylight.controller.clustering.services.CacheExistException;
30 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
31 import org.opendaylight.controller.clustering.services.IClusterServices;
32 import org.opendaylight.controller.configuration.IConfigurationAware;
33 import org.opendaylight.controller.containermanager.IContainerAuthorization;
34 import org.opendaylight.controller.sal.authorization.AuthResultEnum;
35 import org.opendaylight.controller.sal.authorization.IResourceAuthorization;
36 import org.opendaylight.controller.sal.authorization.UserLevel;
37 import org.opendaylight.controller.sal.utils.StatusCode;
38 import org.opendaylight.controller.sal.utils.GlobalConstants;
39 import org.opendaylight.controller.sal.utils.IObjectReader;
40 import org.opendaylight.controller.sal.utils.ObjectReader;
41 import org.opendaylight.controller.sal.utils.ObjectWriter;
42 import org.opendaylight.controller.sal.utils.Status;
43 import org.opendaylight.controller.usermanager.AuthResponse;
44 import org.opendaylight.controller.usermanager.AuthenticatedUser;
45 import org.opendaylight.controller.usermanager.AuthorizationConfig;
46 import org.opendaylight.controller.usermanager.IAAAProvider;
47 import org.opendaylight.controller.usermanager.ISessionManager;
48 import org.opendaylight.controller.usermanager.IUserManager;
49 import org.opendaylight.controller.usermanager.ServerConfig;
50 import org.opendaylight.controller.usermanager.UserConfig;
51 import org.opendaylight.controller.usermanager.security.SessionManager;
52 import org.opendaylight.controller.usermanager.security.UserSecurityContextRepository;
54 import org.osgi.framework.BundleContext;
55 import org.osgi.framework.FrameworkUtil;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58 import org.springframework.security.authentication.AuthenticationProvider;
59 import org.springframework.security.authentication.AuthenticationServiceException;
60 import org.springframework.security.authentication.BadCredentialsException;
61 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
62 import org.springframework.security.core.Authentication;
63 import org.springframework.security.core.AuthenticationException;
64 import org.springframework.security.core.userdetails.User;
65 import org.springframework.security.core.userdetails.UserDetails;
66 import org.springframework.security.core.userdetails.UsernameNotFoundException;
67 import org.springframework.security.web.context.SecurityContextRepository;
70 * The internal implementation of the User Manager.
72 public class UserManager implements IUserManager, IObjectReader,
73 IConfigurationAware, CommandProvider, AuthenticationProvider {
74 private static final Logger logger = LoggerFactory.getLogger(UserManager.class);
75 private static final String defaultAdmin = "admin";
76 private static final String defaultAdminPassword = "admin";
77 private static final String defaultAdminRole = UserLevel.NETWORKADMIN.toString();
78 private static final String ROOT = GlobalConstants.STARTUPHOME.toString();
79 private static final String usersFileName = ROOT + "users.conf";
80 private static final String serversFileName = ROOT + "servers.conf";
81 private static final String authFileName = ROOT + "authorization.conf";
82 private ConcurrentMap<String, UserConfig> localUserConfigList;
83 private ConcurrentMap<String, ServerConfig> remoteServerConfigList;
84 // local authorization info for remotely authenticated users
85 private ConcurrentMap<String, AuthorizationConfig> authorizationConfList;
86 private ConcurrentMap<String, AuthenticatedUser> activeUsers;
87 private ConcurrentMap<String, IAAAProvider> authProviders;
88 private IClusterGlobalServices clusterGlobalService = null;
89 private SecurityContextRepository securityContextRepo = new UserSecurityContextRepository();
90 private IContainerAuthorization containerAuthorizationClient;
91 private Set<IResourceAuthorization> applicationAuthorizationClients;
92 private ISessionManager sessionMgr = new SessionManager();
94 public boolean addAAAProvider(IAAAProvider provider) {
95 if (provider == null || provider.getName() == null
96 || provider.getName().trim().isEmpty()) {
99 if (authProviders.get(provider.getName()) != null) {
103 authProviders.put(provider.getName(), provider);
107 public void removeAAAProvider(IAAAProvider provider) {
108 authProviders.remove(provider.getName());
111 public IAAAProvider getAAAProvider(String name) {
112 return authProviders.get(name);
116 public Set<String> getAAAProviderNames() {
117 return authProviders.keySet();
120 private void allocateCaches() {
121 this.applicationAuthorizationClients = Collections.synchronizedSet(new HashSet<IResourceAuthorization>());
122 if (clusterGlobalService == null) {
123 logger.error("un-initialized clusterGlobalService, can't create cache");
128 clusterGlobalService.createCache("usermanager.localUserConfigList",
129 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
131 clusterGlobalService.createCache(
132 "usermanager.remoteServerConfigList",
133 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
135 clusterGlobalService.createCache(
136 "usermanager.authorizationConfList",
137 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
139 clusterGlobalService.createCache("usermanager.activeUsers",
140 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
141 } catch (CacheConfigException cce) {
142 logger.error("Cache configuration invalid - check cache mode");
143 } catch (CacheExistException ce) {
144 logger.debug("Skipping cache creation as already present");
148 @SuppressWarnings({ "unchecked" })
149 private void retrieveCaches() {
150 if (clusterGlobalService == null) {
151 logger.error("un-initialized clusterService, can't retrieve cache");
155 activeUsers = (ConcurrentMap<String, AuthenticatedUser>) clusterGlobalService
156 .getCache("usermanager.activeUsers");
157 if (activeUsers == null) {
158 logger.error("Failed to get cache for activeUsers");
161 localUserConfigList = (ConcurrentMap<String, UserConfig>) clusterGlobalService
162 .getCache("usermanager.localUserConfigList");
163 if (localUserConfigList == null) {
164 logger.error("Failed to get cache for localUserConfigList");
167 remoteServerConfigList = (ConcurrentMap<String, ServerConfig>) clusterGlobalService
168 .getCache("usermanager.remoteServerConfigList");
169 if (remoteServerConfigList == null) {
170 logger.error("Failed to get cache for remoteServerConfigList");
173 authorizationConfList = (ConcurrentMap<String, AuthorizationConfig>) clusterGlobalService
174 .getCache("usermanager.authorizationConfList");
175 if (authorizationConfList == null) {
176 logger.error("Failed to get cache for authorizationConfList");
180 private void loadConfigurations() {
181 // To encode and decode user and server configuration objects
185 * Do not load local startup file if we already got the configurations
186 * synced from another cluster node
188 if (localUserConfigList.isEmpty()) {
191 if (remoteServerConfigList.isEmpty()) {
194 if (authorizationConfList.isEmpty()) {
199 private void loadSecurityKeys() {
203 private void checkDefaultNetworkAdmin() {
204 // If startup config is not there, it's old or it was deleted,
205 // need to add Default Network Admin User
206 if (!localUserConfigList.containsKey(defaultAdmin)) {
207 List<String> roles = new ArrayList<String>(1);
208 roles.add(defaultAdminRole);
209 localUserConfigList.put(defaultAdmin, new UserConfig(defaultAdmin, defaultAdminPassword, roles));
214 public AuthResultEnum authenticate(String userName, String password) {
215 IAAAProvider aaaClient;
216 AuthResponse rcResponse = null;
217 AuthenticatedUser result;
218 boolean remotelyAuthenticated = false;
219 boolean authorizationInfoIsPresent = false;
220 boolean authorized = false;
223 * Attempt remote authentication first if server is configured
225 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
226 String protocol = aaaServer.getProtocol();
227 aaaClient = this.getAAAProvider(protocol);
228 if (aaaClient != null) {
229 rcResponse = aaaClient.authService(userName, password,
230 aaaServer.getAddress(), aaaServer.getSecret());
231 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
233 "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
234 userName, aaaServer.getAddress());
235 remotelyAuthenticated = true;
237 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
239 "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
240 new Object[] { userName, aaaServer.getAddress(),
241 rcResponse.getStatus().toString() });
244 "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
245 new Object[] { userName, aaaServer.getAddress(),
246 rcResponse.getStatus().toString() });
251 if (!remotelyAuthenticated) {
252 UserConfig localUser = this.localUserConfigList.get(userName);
253 if (localUser == null) {
255 "Local Authentication Failed for User:\"{}\", Reason: "
256 + "user not found in Local Database", userName);
257 return (AuthResultEnum.AUTH_INVALID_LOC_USER);
259 rcResponse = localUser.authenticate(password);
260 if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
262 "Local Authentication Failed for User: \"{}\", Reason: {}",
263 userName, rcResponse.getStatus().toString());
265 return (rcResponse.getStatus());
267 logger.info("Local Authentication Succeeded for User: \"{}\"",
272 * Authentication succeeded
274 result = new AuthenticatedUser(userName);
277 * Extract attributes from response All the information we are
278 * interested in is in the first Cisco VSA (vendor specific attribute).
279 * Just process the first VSA and return
281 String attributes = (rcResponse.getData() != null && !rcResponse
282 .getData().isEmpty()) ? rcResponse.getData().get(0) : null;
285 * Check if the authorization information is present
287 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
290 * The AAA server was only used to perform the authentication Look for
291 * locally stored authorization info for this user If found, add the
292 * data to the rcResponse
294 if (remotelyAuthenticated && !authorizationInfoIsPresent) {
296 "No Remote Authorization Info provided by Server for User: \"{}\"",
299 "Looking for Local Authorization Info for User: \"{}\"",
302 AuthorizationConfig resource = authorizationConfList.get(userName);
303 if (resource != null) {
304 logger.info("Found Local Authorization Info for User: \"{}\"",
306 attributes = resource.getRolesString();
309 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
313 * Common response parsing for local & remote authenticated user Looking
314 * for authorized resources, detecting attributes' validity
316 if (authorizationInfoIsPresent) {
317 // Identifying the administrative role
318 result.setRoleList(attributes.split(" "));
321 logger.info("Not able to find Authorization Info for User: \"{}\"",
326 * Add profile for authenticated user
328 putUserInActiveList(userName, result);
330 logger.info("User \"{}\" authorized for the following role(s): {}",
331 userName, result.getUserRoles());
333 logger.info("User \"{}\" Not Authorized for any role ", userName);
336 return rcResponse.getStatus();
339 // Check in the attributes string whether or not authorization information
341 private boolean checkAuthorizationInfo(String attributes) {
342 return (attributes != null && !attributes.isEmpty());
345 private void putUserInActiveList(String user, AuthenticatedUser result) {
346 activeUsers.put(user, result);
349 private void removeUserFromActiveList(String user) {
350 if (!activeUsers.containsKey(user)) {
351 // as cookie persists in cache, we can get logout for unexisting
355 activeUsers.remove(user);
359 public Status saveLocalUserList() {
360 return saveLocalUserListInternal();
363 private Status saveLocalUserListInternal() {
364 ObjectWriter objWriter = new ObjectWriter();
365 return objWriter.write(new ConcurrentHashMap<String, UserConfig>(
366 localUserConfigList), usersFileName);
370 public Status saveAAAServerList() {
371 return saveAAAServerListInternal();
374 private Status saveAAAServerListInternal() {
375 ObjectWriter objWriter = new ObjectWriter();
376 return objWriter.write(new ConcurrentHashMap<String, ServerConfig>(
377 remoteServerConfigList), serversFileName);
381 public Status saveAuthorizationList() {
382 return saveAuthorizationListInternal();
385 private Status saveAuthorizationListInternal() {
386 ObjectWriter objWriter = new ObjectWriter();
387 return objWriter.write(
388 new ConcurrentHashMap<String, AuthorizationConfig>(
389 authorizationConfList), authFileName);
393 public Object readObject(ObjectInputStream ois)
394 throws FileNotFoundException, IOException, ClassNotFoundException {
395 // Perform the class deserialization locally, from inside the package
396 // where the class is defined
397 return ois.readObject();
400 @SuppressWarnings("unchecked")
401 private void loadUserConfig() {
402 ObjectReader objReader = new ObjectReader();
403 ConcurrentMap<String, UserConfig> confList = (ConcurrentMap<String, UserConfig>) objReader
404 .read(this, usersFileName);
406 if (confList == null) {
410 for (UserConfig conf : confList.values()) {
411 addRemoveLocalUserInternal(conf, false);
415 @SuppressWarnings("unchecked")
416 private void loadServerConfig() {
417 ObjectReader objReader = new ObjectReader();
418 ConcurrentMap<String, ServerConfig> confList = (ConcurrentMap<String, ServerConfig>) objReader
419 .read(this, serversFileName);
421 if (confList == null) {
425 for (ServerConfig conf : confList.values()) {
430 @SuppressWarnings("unchecked")
431 private void loadAuthConfig() {
432 ObjectReader objReader = new ObjectReader();
433 ConcurrentMap<String, AuthorizationConfig> confList = (ConcurrentMap<String, AuthorizationConfig>) objReader
434 .read(this, authFileName);
436 if (confList == null) {
440 for (AuthorizationConfig conf : confList.values()) {
446 * Interaction with GUI START
448 private Status addRemoveLocalUser(UserConfig AAAconf, boolean delete) {
449 // UserConfig Validation check
450 Status validCheck = AAAconf.validate();
451 if (!validCheck.isSuccess()) {
455 String user = AAAconf.getUser();
457 // Check default admin user
458 if (user.equals(UserManager.defaultAdmin)) {
459 String msg = "Invalid Request: Default Network Admin User cannot be " + ((delete)? "removed" : "added");
461 return new Status(StatusCode.NOTALLOWED, msg);
464 // Check user presence/conflict
465 StatusCode statusCode = null;
466 String reason = null;
467 if (delete && !localUserConfigList.containsKey(user)) {
468 reason = "not found";
469 statusCode = StatusCode.NOTFOUND;
470 } else if (!delete && localUserConfigList.containsKey(user)) {
471 reason = "already present";
472 statusCode = StatusCode.CONFLICT;
474 if (statusCode != null) {
475 String msg = String.format("User %s %s in configuration database", user, reason);
477 return new Status(statusCode, msg);
480 return addRemoveLocalUserInternal(AAAconf, delete);
483 private Status addRemoveLocalUserInternal(UserConfig AAAconf, boolean delete) {
484 // Update Config database
486 localUserConfigList.remove(AAAconf.getUser());
488 * A user account has been removed form local database, we assume
489 * admin does not want this user to stay connected, in case he has
490 * an open session. So we clean the active list as well.
492 removeUserFromActiveList(AAAconf.getUser());
494 localUserConfigList.put(AAAconf.getUser(), AAAconf);
497 return new Status(StatusCode.SUCCESS);
500 private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
502 if (!AAAconf.isValid()) {
503 String msg = "Invalid Server configuration";
505 return new Status(StatusCode.BADREQUEST, msg);
508 // Update configuration database
510 remoteServerConfigList.remove(AAAconf.getAddress());
512 remoteServerConfigList.put(AAAconf.getAddress(), AAAconf);
515 return new Status(StatusCode.SUCCESS);
518 private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
519 Status configCheck = AAAconf.validate();
520 if (!configCheck.isSuccess()) {
521 String msg = "Invalid Authorization configuration: "
522 + configCheck.getDescription();
524 return new Status(StatusCode.BADREQUEST, msg);
527 // Update configuration database
529 authorizationConfList.remove(AAAconf.getUser());
531 authorizationConfList.put(AAAconf.getUser(), AAAconf);
534 return new Status(StatusCode.SUCCESS);
538 public Status addLocalUser(UserConfig AAAconf) {
539 return addRemoveLocalUser(AAAconf, false);
543 public Status removeLocalUser(UserConfig AAAconf) {
544 return addRemoveLocalUser(AAAconf, true);
548 public Status removeLocalUser(String userName) {
549 if (userName == null || userName.trim().isEmpty()) {
550 return new Status(StatusCode.BADREQUEST, "Invalid user name");
553 if (!localUserConfigList.containsKey(userName)) {
554 return new Status(StatusCode.NOTFOUND, "User does not exist");
557 return addRemoveLocalUser(localUserConfigList.get(userName), true);
561 public Status addAAAServer(ServerConfig AAAconf) {
562 return addRemoveAAAServer(AAAconf, false);
566 public Status removeAAAServer(ServerConfig AAAconf) {
567 return addRemoveAAAServer(AAAconf, true);
571 public Status addAuthInfo(AuthorizationConfig AAAconf) {
572 return addRemoveAuthInfo(AAAconf, false);
576 public Status removeAuthInfo(AuthorizationConfig AAAconf) {
577 return addRemoveAuthInfo(AAAconf, true);
581 public List<UserConfig> getLocalUserList() {
582 return new ArrayList<UserConfig>(localUserConfigList.values());
586 public List<ServerConfig> getAAAServerList() {
587 return new ArrayList<ServerConfig>(remoteServerConfigList.values());
591 public List<AuthorizationConfig> getAuthorizationList() {
592 return new ArrayList<AuthorizationConfig>(
593 authorizationConfList.values());
597 public Status changeLocalUserPassword(String user, String curPassword, String newPassword) {
598 UserConfig targetConfigEntry = null;
600 // update configuration entry
601 targetConfigEntry = localUserConfigList.get(user);
602 if (targetConfigEntry == null) {
603 return new Status(StatusCode.NOTFOUND, "User not found");
605 Status status = targetConfigEntry.update(curPassword, newPassword, null);
606 if (!status.isSuccess()) {
609 // Trigger cluster update
610 localUserConfigList.put(user, targetConfigEntry);
612 logger.info("Password changed for User \"{}\"", user);
618 public void userLogout(String userName) {
619 // TODO: if user was authenticated through AAA server, send
620 // Acct-Status-Type=stop message to server with logout as reason
621 removeUserFromActiveList(userName);
622 logger.info("User \"{}\" logged out", userName);
626 * This function will get called by http session mgr when session times out
629 public void userTimedOut(String userName) {
630 // TODO: if user was authenticated through AAA server, send
631 // Acct-Status-Type=stop message to server with timeout as reason
632 removeUserFromActiveList(userName);
633 logger.info("User \"{}\" timed out", userName);
637 public String getAccessDate(String user) {
638 return this.activeUsers.get(user).getAccessDate();
642 public synchronized Map<String, List<String>> getUserLoggedIn() {
643 Map<String, List<String>> loggedInList = new HashMap<String, List<String>>();
644 for (Map.Entry<String, AuthenticatedUser> user : activeUsers.entrySet()) {
645 String userNameShow = user.getKey();
646 loggedInList.put(userNameShow, user.getValue().getUserRoles());
651 public void _umAddUser(CommandInterpreter ci) {
652 String userName = ci.nextArgument();
653 String password = ci.nextArgument();
654 String role = ci.nextArgument();
656 List<String> roles = new ArrayList<String>();
657 while (role != null) {
658 if (!role.trim().isEmpty()) {
661 role = ci.nextArgument();
664 if (userName == null || userName.trim().isEmpty() || password == null || password.trim().isEmpty()
665 || roles.isEmpty()) {
666 ci.println("Invalid Arguments");
667 ci.println("umAddUser <user_name> <password> <user_role>");
670 ci.print(this.addLocalUser(new UserConfig(userName, password, roles)));
673 public void _umRemUser(CommandInterpreter ci) {
674 String userName = ci.nextArgument();
676 if (userName == null || userName.trim().isEmpty()) {
677 ci.println("Invalid Arguments");
678 ci.println("umRemUser <user_name>");
681 UserConfig target = localUserConfigList.get(userName);
682 if (target == null) {
683 ci.println("User not found");
686 ci.println(this.removeLocalUser(target));
689 public void _umGetUsers(CommandInterpreter ci) {
690 for (UserConfig conf : this.getLocalUserList()) {
691 ci.println(conf.getUser() + " " + conf.getRoles());
695 public void _addAAAServer(CommandInterpreter ci) {
696 String server = ci.nextArgument();
697 String secret = ci.nextArgument();
698 String protocol = ci.nextArgument();
700 if (server == null || secret == null || protocol == null) {
701 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
704 ServerConfig s = new ServerConfig(server, secret, protocol);
708 public void _removeAAAServer(CommandInterpreter ci) {
709 String server = ci.nextArgument();
710 String secret = ci.nextArgument();
711 String protocol = ci.nextArgument();
713 if (server == null || secret == null || protocol == null) {
714 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
717 ServerConfig s = new ServerConfig(server, secret, protocol);
721 public void _printAAAServers(CommandInterpreter ci) {
722 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
723 ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
728 public String getHelp() {
729 StringBuffer help = new StringBuffer();
730 return help.toString();
733 void setClusterGlobalService(IClusterGlobalServices s) {
734 logger.debug("Cluster Service Global set");
735 this.clusterGlobalService = s;
738 void unsetClusterGlobalService(IClusterGlobalServices s) {
739 if (this.clusterGlobalService == s) {
740 logger.debug("Cluster Service Global removed!");
741 this.clusterGlobalService = null;
745 void unsetContainerAuthClient(IContainerAuthorization s) {
746 if (this.containerAuthorizationClient == s) {
747 this.containerAuthorizationClient = null;
751 void setContainerAuthClient(IContainerAuthorization s) {
752 this.containerAuthorizationClient = s;
755 void setAppAuthClient(IResourceAuthorization s) {
756 this.applicationAuthorizationClients.add(s);
759 void unsetAppAuthClient(IResourceAuthorization s) {
760 this.applicationAuthorizationClients.remove(s);
764 * Function called by the dependency manager when all the required
765 * dependencies are satisfied
772 * Function called by the dependency manager when at least one dependency
773 * become unsatisfied or when the component is shutting down because for
774 * example bundle is being stopped.
781 * Function called by dependency manager after "init ()" is called and after
782 * the services provided by the class are registered in the service registry
786 authProviders = new ConcurrentHashMap<String, IAAAProvider>();
787 // Instantiate cluster synced variables
791 // Read startup configuration and populate databases
792 loadConfigurations();
794 // Make sure default Network Admin account is there
795 checkDefaultNetworkAdmin();
796 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
798 bundleContext.registerService(CommandProvider.class.getName(), this,
803 * Function called by the dependency manager before the services exported by
804 * the component are unregistered, this will be followed by a "destroy ()"
812 public List<String> getUserRoles(String userName) {
813 List<String> roles = null;
814 if (userName != null) {
816 * First look in active users then in local configured users,
817 * finally in local authorized users
819 if (activeUsers.containsKey(userName)) {
820 roles = activeUsers.get(userName).getUserRoles();
821 } else if (localUserConfigList.containsKey(userName)) {
822 roles = localUserConfigList.get(userName).getRoles();
823 } else if (authorizationConfList.containsKey(userName)) {
824 roles = authorizationConfList.get(userName).getRoles();
827 return (roles == null) ? new ArrayList<String>(0) : roles;
831 public UserLevel getUserLevel(String username) {
832 // Returns the highest controller user level for the passed user
833 List<String> rolesNames = getUserRoles(username);
835 if (rolesNames.isEmpty()) {
836 return UserLevel.NOUSER;
839 // Check against the well known controller roles first
840 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
841 return UserLevel.SYSTEMADMIN;
843 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
844 return UserLevel.NETWORKADMIN;
846 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
847 return UserLevel.NETWORKOPERATOR;
849 // Check if container user now
850 if (containerAuthorizationClient != null) {
851 for (String roleName : rolesNames) {
852 if (containerAuthorizationClient.isApplicationRole(roleName)) {
853 return UserLevel.CONTAINERUSER;
857 // Finally check if application user
858 if (applicationAuthorizationClients != null) {
859 for (String roleName : rolesNames) {
860 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
861 if (client.isApplicationRole(roleName)) {
862 return UserLevel.APPUSER;
867 return UserLevel.NOUSER;
872 public List<UserLevel> getUserLevels(String username) {
873 // Returns the controller user levels for the passed user
874 List<String> rolesNames = getUserRoles(username);
875 List<UserLevel> levels = new ArrayList<UserLevel>();
877 if (rolesNames.isEmpty()) {
881 // Check against the well known controller roles first
882 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
883 levels.add(UserLevel.SYSTEMADMIN);
885 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
886 levels.add(UserLevel.NETWORKADMIN);
888 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
889 levels.add(UserLevel.NETWORKOPERATOR);
891 // Check if container user now
892 if (containerAuthorizationClient != null) {
893 for (String roleName : rolesNames) {
894 if (containerAuthorizationClient.isApplicationRole(roleName)) {
895 levels.add(UserLevel.CONTAINERUSER);
900 // Finally check if application user
901 if (applicationAuthorizationClients != null) {
902 for (String roleName : rolesNames) {
903 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
904 if (client.isApplicationRole(roleName)) {
905 levels.add(UserLevel.APPUSER);
915 public Status saveConfiguration() {
916 boolean success = true;
917 Status ret = saveLocalUserList();
918 if (!ret.isSuccess()) {
921 ret = saveAAAServerList();
922 if (!ret.isSuccess()) {
925 ret = saveAuthorizationList();
926 if (!ret.isSuccess()) {
931 return new Status(StatusCode.SUCCESS);
934 return new Status(StatusCode.INTERNALERROR, "Failed to save user configurations");
938 public UserDetails loadUserByUsername(String username)
939 throws UsernameNotFoundException {
940 AuthenticatedUser user = activeUsers.get(username);
943 boolean enabled = true;
944 boolean accountNonExpired = true;
945 boolean credentialsNonExpired = true;
946 boolean accountNonLocked = true;
948 return new User(username, localUserConfigList.get(username)
949 .getPassword(), enabled, accountNonExpired,
950 credentialsNonExpired, accountNonLocked,
951 user.getGrantedAuthorities(getUserLevel(username)));
953 throw new UsernameNotFoundException("User not found " + username);
958 public boolean supports(Class<?> authentication) {
959 return UsernamePasswordAuthenticationToken.class
960 .isAssignableFrom(authentication);
965 public SecurityContextRepository getSecurityContextRepo() {
966 return securityContextRepo;
969 public void setSecurityContextRepo(
970 SecurityContextRepository securityContextRepo) {
971 this.securityContextRepo = securityContextRepo;
975 public Authentication authenticate(Authentication authentication)
976 throws AuthenticationException {
978 if (StringUtils.isBlank((String) authentication.getCredentials())
979 || StringUtils.isBlank((String) authentication.getPrincipal())) {
980 throw new BadCredentialsException(
981 "Username or credentials did not match");
984 AuthResultEnum result = authenticate(
985 (String) authentication.getPrincipal(),
986 (String) authentication.getCredentials());
987 if (result.equals(AuthResultEnum.AUTHOR_PASS)
988 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
989 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
991 AuthenticatedUser user = activeUsers.get(authentication
992 .getPrincipal().toString());
995 throw new AuthenticationServiceException(
996 "Authentication Failure");
999 authentication = new UsernamePasswordAuthenticationToken(
1000 authentication.getPrincipal(),
1001 authentication.getCredentials(),
1002 user.getGrantedAuthorities(getUserLevel(authentication
1004 return authentication;
1007 throw new BadCredentialsException(
1008 "Username or credentials did not match");
1013 // Following are setters for use in unit testing
1014 void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1016 this.localUserConfigList = ucl;
1020 void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1022 this.remoteServerConfigList = scl;
1026 void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1028 this.authorizationConfList = acl;
1032 void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1034 this.activeUsers = au;
1038 void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1040 this.authProviders = ap;
1045 public ISessionManager getSessionManager() {
1046 return this.sessionMgr;
1049 public void setSessionMgr(ISessionManager sessionMgr) {
1050 this.sessionMgr = sessionMgr;
1054 public String getPassword(String username) {
1055 return localUserConfigList.get(username).getPassword();
1059 public boolean isRoleInUse(String role) {
1060 if (role == null || role.isEmpty()) {
1063 // Check against controller roles
1064 if (role.equals(UserLevel.SYSTEMADMIN.toString())
1065 || role.equals(UserLevel.NETWORKADMIN.toString())
1066 || role.equals(UserLevel.NETWORKOPERATOR.toString())) {
1069 // Check if container roles
1070 if (containerAuthorizationClient != null) {
1071 if (containerAuthorizationClient.isApplicationRole(role)) {
1075 // Finally if application role
1076 if (applicationAuthorizationClients != null) {
1077 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
1078 if (client.isApplicationRole(role)) {