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;
12 import java.io.FileInputStream;
13 import java.io.FileNotFoundException;
14 import java.io.IOException;
15 import java.io.ObjectInputStream;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.EnumSet;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.ConcurrentMap;
27 import org.apache.commons.lang3.StringUtils;
28 import org.eclipse.osgi.framework.console.CommandInterpreter;
29 import org.eclipse.osgi.framework.console.CommandProvider;
30 import org.opendaylight.controller.clustering.services.CacheConfigException;
31 import org.opendaylight.controller.clustering.services.CacheExistException;
32 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
33 import org.opendaylight.controller.clustering.services.IClusterServices;
34 import org.opendaylight.controller.configuration.ConfigurationObject;
35 import org.opendaylight.controller.configuration.IConfigurationAware;
36 import org.opendaylight.controller.configuration.IConfigurationService;
37 import org.opendaylight.controller.containermanager.IContainerAuthorization;
38 import org.opendaylight.controller.sal.authorization.AuthResultEnum;
39 import org.opendaylight.controller.sal.authorization.IResourceAuthorization;
40 import org.opendaylight.controller.sal.authorization.UserLevel;
41 import org.opendaylight.controller.sal.utils.IObjectReader;
42 import org.opendaylight.controller.sal.utils.Status;
43 import org.opendaylight.controller.sal.utils.StatusCode;
44 import org.opendaylight.controller.usermanager.AuthResponse;
45 import org.opendaylight.controller.usermanager.AuthenticatedUser;
46 import org.opendaylight.controller.usermanager.AuthorizationConfig;
47 import org.opendaylight.controller.usermanager.IAAAProvider;
48 import org.opendaylight.controller.usermanager.ISessionManager;
49 import org.opendaylight.controller.usermanager.IUserManager;
50 import org.opendaylight.controller.usermanager.ServerConfig;
51 import org.opendaylight.controller.usermanager.UserConfig;
52 import org.opendaylight.controller.usermanager.security.SessionManager;
53 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 DEFAULT_ADMIN = "admin";
76 private static final String DEFAULT_ADMIN_PASSWORD = "admin";
77 private static final String DEFAULT_ADMIN_ROLE = UserLevel.NETWORKADMIN.toString();
78 private static final String USERS_FILE_NAME = "users.conf";
79 private static final String SERVERS_FILE_NAME = "servers.conf";
80 private static final String AUTH_FILE_NAME = "authorization.conf";
81 private static final String RECOVERY_FILE = "NETWORK_ADMIN_PASSWORD_RECOVERY";
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 IConfigurationService configurationService;
90 private SecurityContextRepository securityContextRepo = new UserSecurityContextRepository();
91 private IContainerAuthorization containerAuthorizationClient;
92 private Set<IResourceAuthorization> applicationAuthorizationClients;
93 private ISessionManager sessionMgr = new SessionManager();
94 protected enum Command {
96 MODIFY("modify", "modified"),
97 REMOVE("remove", "removed");
98 private String action;
99 private String postAction;
100 private Command(String action, String postAction) {
101 this.action = action;
102 this.postAction = postAction;
105 public String getAction() {
109 public String getPostAction() {
114 public boolean addAAAProvider(IAAAProvider provider) {
115 if (provider == null || provider.getName() == null
116 || provider.getName().trim().isEmpty()) {
119 if (authProviders.get(provider.getName()) != null) {
123 authProviders.put(provider.getName(), provider);
127 public void removeAAAProvider(IAAAProvider provider) {
128 authProviders.remove(provider.getName());
131 public IAAAProvider getAAAProvider(String name) {
132 return authProviders.get(name);
136 public Set<String> getAAAProviderNames() {
137 return authProviders.keySet();
140 private void allocateCaches() {
141 this.applicationAuthorizationClients = Collections.synchronizedSet(new HashSet<IResourceAuthorization>());
142 if (clusterGlobalService == null) {
143 logger.error("un-initialized clusterGlobalService, can't create cache");
148 clusterGlobalService.createCache("usermanager.localUserConfigList",
149 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
151 clusterGlobalService.createCache(
152 "usermanager.remoteServerConfigList",
153 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
155 clusterGlobalService.createCache(
156 "usermanager.authorizationConfList",
157 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
159 clusterGlobalService.createCache("usermanager.activeUsers",
160 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
161 } catch (CacheConfigException cce) {
162 logger.error("Cache configuration invalid - check cache mode");
163 } catch (CacheExistException ce) {
164 logger.debug("Skipping cache creation as already present");
168 @SuppressWarnings({ "unchecked" })
169 private void retrieveCaches() {
170 if (clusterGlobalService == null) {
171 logger.error("un-initialized clusterService, can't retrieve cache");
175 activeUsers = (ConcurrentMap<String, AuthenticatedUser>) clusterGlobalService
176 .getCache("usermanager.activeUsers");
177 if (activeUsers == null) {
178 logger.error("Failed to get cache for activeUsers");
181 localUserConfigList = (ConcurrentMap<String, UserConfig>) clusterGlobalService
182 .getCache("usermanager.localUserConfigList");
183 if (localUserConfigList == null) {
184 logger.error("Failed to get cache for localUserConfigList");
187 remoteServerConfigList = (ConcurrentMap<String, ServerConfig>) clusterGlobalService
188 .getCache("usermanager.remoteServerConfigList");
189 if (remoteServerConfigList == null) {
190 logger.error("Failed to get cache for remoteServerConfigList");
193 authorizationConfList = (ConcurrentMap<String, AuthorizationConfig>) clusterGlobalService
194 .getCache("usermanager.authorizationConfList");
195 if (authorizationConfList == null) {
196 logger.error("Failed to get cache for authorizationConfList");
200 private void loadConfigurations() {
201 // To encode and decode user and server configuration objects
204 * Do not load local startup file if we are not the coordinator
211 private void loadSecurityKeys() {
215 private void checkDefaultNetworkAdmin() {
217 * If startup config is not there, it's old or it was deleted or if a
218 * password recovery was run, need to add Default Network Admin User
220 if (!localUserConfigList.containsKey(DEFAULT_ADMIN)) {
221 List<String> roles = new ArrayList<String>(1);
222 roles.add(DEFAULT_ADMIN_ROLE);
223 // Need to skip the strong password check for the default admin
224 UserConfig defaultAdmin = UserConfig.getUncheckedUserConfig(UserManager.DEFAULT_ADMIN,
225 UserManager.DEFAULT_ADMIN_PASSWORD, roles);
226 localUserConfigList.put(UserManager.DEFAULT_ADMIN, defaultAdmin);
230 private void checkPasswordRecovery() {
231 final String fileDescription = "Default Network Administrator password recovery file";
233 FileInputStream fis = new FileInputStream(UserManager.RECOVERY_FILE);
235 * Recovery file detected, remove current default network
236 * administrator entry from local users configuration list.
237 * Warn user and delete recovery file.
239 this.localUserConfigList.remove(UserManager.DEFAULT_ADMIN);
240 logger.info("Default Network Administrator password has been reset to factory default.");
241 logger.info("Please change the default Network Administrator password as soon as possible");
242 File filePointer = new File(UserManager.RECOVERY_FILE);
243 boolean status = filePointer.delete();
245 logger.warn("Failed to delete {}", fileDescription);
247 logger.trace("{} deleted", fileDescription);
250 } catch (FileNotFoundException fnf) {
251 logger.trace("{} not present", fileDescription);
252 } catch (IOException e) {
253 logger.warn("Failed to close file stream for {}", fileDescription);
258 public AuthResultEnum authenticate(String userName, String password) {
259 IAAAProvider aaaClient;
260 AuthResponse rcResponse = null;
261 AuthenticatedUser result;
262 boolean remotelyAuthenticated = false;
263 boolean authorizationInfoIsPresent = false;
264 boolean authorized = false;
267 * Attempt remote authentication first if server is configured
269 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
270 String protocol = aaaServer.getProtocol();
271 aaaClient = this.getAAAProvider(protocol);
272 if (aaaClient != null) {
273 rcResponse = aaaClient.authService(userName, password,
274 aaaServer.getAddress(), aaaServer.getSecret());
275 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
277 "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
278 userName, aaaServer.getAddress());
279 remotelyAuthenticated = true;
281 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
283 "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
284 new Object[] { userName, aaaServer.getAddress(),
285 rcResponse.getStatus().toString() });
288 "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
289 new Object[] { userName, aaaServer.getAddress(),
290 rcResponse.getStatus().toString() });
295 if (!remotelyAuthenticated) {
296 UserConfig localUser = this.localUserConfigList.get(userName);
297 if (localUser == null) {
299 "Local Authentication Failed for User:\"{}\", Reason: "
300 + "user not found in Local Database", userName);
301 return (AuthResultEnum.AUTH_INVALID_LOC_USER);
303 rcResponse = localUser.authenticate(password);
304 if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
306 "Local Authentication Failed for User: \"{}\", Reason: {}",
307 userName, rcResponse.getStatus().toString());
309 return (rcResponse.getStatus());
311 logger.info("Local Authentication Succeeded for User: \"{}\"",
316 * Authentication succeeded
318 result = new AuthenticatedUser(userName);
321 * Extract attributes from response All the information we are
322 * interested in is in the first Cisco VSA (vendor specific attribute).
323 * Just process the first VSA and return
325 String attributes = (rcResponse.getData() != null && !rcResponse
326 .getData().isEmpty()) ? rcResponse.getData().get(0) : null;
329 * Check if the authorization information is present
331 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
334 * The AAA server was only used to perform the authentication Look for
335 * locally stored authorization info for this user If found, add the
336 * data to the rcResponse
338 if (remotelyAuthenticated && !authorizationInfoIsPresent) {
340 "No Remote Authorization Info provided by Server for User: \"{}\"",
343 "Looking for Local Authorization Info for User: \"{}\"",
346 AuthorizationConfig resource = authorizationConfList.get(userName);
347 if (resource != null) {
348 logger.info("Found Local Authorization Info for User: \"{}\"",
350 attributes = resource.getRolesString();
353 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
357 * Common response parsing for local & remote authenticated user Looking
358 * for authorized resources, detecting attributes' validity
360 if (authorizationInfoIsPresent) {
361 // Identifying the administrative role
362 result.setRoleList(attributes.split(" "));
365 logger.info("Not able to find Authorization Info for User: \"{}\"",
370 * Add profile for authenticated user
372 putUserInActiveList(userName, result);
374 logger.info("User \"{}\" authorized for the following role(s): {}",
375 userName, result.getUserRoles());
377 logger.info("User \"{}\" Not Authorized for any role ", userName);
380 return rcResponse.getStatus();
383 // Check in the attributes string whether or not authorization information
385 private boolean checkAuthorizationInfo(String attributes) {
386 return (attributes != null && !attributes.isEmpty());
389 private void putUserInActiveList(String user, AuthenticatedUser result) {
390 activeUsers.put(user, result);
393 private void removeUserFromActiveList(String user) {
394 if (!activeUsers.containsKey(user)) {
395 // as cookie persists in cache, we can get logout for unexisting
399 activeUsers.remove(user);
403 public Status saveLocalUserList() {
404 return saveLocalUserListInternal();
407 private Status saveLocalUserListInternal() {
408 return configurationService.persistConfiguration(
409 new ArrayList<ConfigurationObject>(localUserConfigList.values()), USERS_FILE_NAME);
413 public Status saveAAAServerList() {
414 return saveAAAServerListInternal();
417 private Status saveAAAServerListInternal() {
418 return configurationService.persistConfiguration(
419 new ArrayList<ConfigurationObject>(remoteServerConfigList.values()), SERVERS_FILE_NAME);
423 public Status saveAuthorizationList() {
424 return saveAuthorizationListInternal();
427 private Status saveAuthorizationListInternal() {
428 return configurationService.persistConfiguration(
429 new ArrayList<ConfigurationObject>(authorizationConfList.values()), AUTH_FILE_NAME);
433 public Object readObject(ObjectInputStream ois)
434 throws FileNotFoundException, IOException, ClassNotFoundException {
435 // Perform the class deserialization locally, from inside the package
436 // where the class is defined
437 return ois.readObject();
440 private void loadUserConfig() {
441 for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, USERS_FILE_NAME)) {
442 addRemoveLocalUserInternal((UserConfig) conf, false);
446 private void loadServerConfig() {
447 for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, SERVERS_FILE_NAME)) {
448 addAAAServer((ServerConfig) conf);
452 private void loadAuthConfig() {
453 for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, AUTH_FILE_NAME)) {
454 addAuthInfo((AuthorizationConfig) conf);
459 * Interaction with GUI START
461 private Status changeLocalUser(UserConfig AAAconf, Command command) {
462 // UserConfig Validation check
463 Status validCheck = AAAconf.validate();
464 if (!validCheck.isSuccess()) {
468 String user = AAAconf.getUser();
470 // Check default admin user
471 if (user.equals(UserManager.DEFAULT_ADMIN)) {
472 String msg = String.format("Invalid Request: Default Network Admin User cannot be %s", command.getPostAction());
474 return new Status(StatusCode.NOTALLOWED, msg);
477 // Check user presence/conflict
478 UserConfig currentAAAconf = localUserConfigList.get(user);
479 StatusCode statusCode = null;
480 String reason = null;
483 if (currentAAAconf != null) {
484 reason = "already present";
485 statusCode = StatusCode.CONFLICT;
490 if (currentAAAconf == null) {
491 reason = "not found";
492 statusCode = StatusCode.NOTFOUND;
499 if (statusCode != null) {
500 String action = String.format("Failed to %s user %s: ", command.getAction(), user);
501 String msg = String.format("User %s %s in configuration database", user, reason);
502 logger.debug(action + msg);
503 return new Status(statusCode, msg);
508 return addRemoveLocalUserInternal(AAAconf, false);
510 addRemoveLocalUserInternal(currentAAAconf, true);
511 return addRemoveLocalUserInternal(AAAconf, false);
513 return addRemoveLocalUserInternal(AAAconf, true);
515 return new Status(StatusCode.INTERNALERROR, "Unknown action");
519 private Status addRemoveLocalUserInternal(UserConfig AAAconf, boolean delete) {
520 // Update Config database
522 localUserConfigList.remove(AAAconf.getUser());
524 * A user account has been removed form local database, we assume
525 * admin does not want this user to stay connected, in case he has
526 * an open session. So we clean the active list as well.
528 removeUserFromActiveList(AAAconf.getUser());
530 localUserConfigList.put(AAAconf.getUser(), AAAconf);
533 return new Status(StatusCode.SUCCESS);
536 private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
538 if (!AAAconf.isValid()) {
539 String msg = "Invalid Server configuration";
541 return new Status(StatusCode.BADREQUEST, msg);
544 // Update configuration database
546 remoteServerConfigList.remove(AAAconf.getAddress());
548 remoteServerConfigList.put(AAAconf.getAddress(), AAAconf);
551 return new Status(StatusCode.SUCCESS);
554 private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
555 Status configCheck = AAAconf.validate();
556 if (!configCheck.isSuccess()) {
557 String msg = "Invalid Authorization configuration: "
558 + configCheck.getDescription();
560 return new Status(StatusCode.BADREQUEST, msg);
563 // Update configuration database
565 authorizationConfList.remove(AAAconf.getUser());
567 authorizationConfList.put(AAAconf.getUser(), AAAconf);
570 return new Status(StatusCode.SUCCESS);
574 public Status addLocalUser(UserConfig AAAconf) {
575 return changeLocalUser(AAAconf, Command.ADD);
579 public Status modifyLocalUser(UserConfig AAAconf) {
580 return changeLocalUser(AAAconf, Command.MODIFY);
584 public Status removeLocalUser(UserConfig AAAconf) {
585 return changeLocalUser(AAAconf, Command.REMOVE);
589 public Status removeLocalUser(String userName) {
590 if (userName == null || userName.trim().isEmpty()) {
591 return new Status(StatusCode.BADREQUEST, "Invalid user name");
594 if (!localUserConfigList.containsKey(userName)) {
595 return new Status(StatusCode.NOTFOUND, "User does not exist");
598 return changeLocalUser(localUserConfigList.get(userName), Command.REMOVE);
602 public Status addAAAServer(ServerConfig AAAconf) {
603 return addRemoveAAAServer(AAAconf, false);
607 public Status removeAAAServer(ServerConfig AAAconf) {
608 return addRemoveAAAServer(AAAconf, true);
612 public Status addAuthInfo(AuthorizationConfig AAAconf) {
613 return addRemoveAuthInfo(AAAconf, false);
617 public Status removeAuthInfo(AuthorizationConfig AAAconf) {
618 return addRemoveAuthInfo(AAAconf, true);
622 public List<UserConfig> getLocalUserList() {
623 return new ArrayList<UserConfig>(localUserConfigList.values());
627 public List<ServerConfig> getAAAServerList() {
628 return new ArrayList<ServerConfig>(remoteServerConfigList.values());
632 public List<AuthorizationConfig> getAuthorizationList() {
633 return new ArrayList<AuthorizationConfig>(
634 authorizationConfList.values());
638 public Status changeLocalUserPassword(String user, String curPassword, String newPassword) {
639 UserConfig targetConfigEntry = null;
641 // update configuration entry
642 targetConfigEntry = localUserConfigList.get(user);
643 if (targetConfigEntry == null) {
644 return new Status(StatusCode.NOTFOUND, "User not found");
646 Status status = targetConfigEntry.update(curPassword, newPassword, null);
647 if (!status.isSuccess()) {
650 // Trigger cluster update
651 localUserConfigList.put(user, targetConfigEntry);
653 logger.trace("Password changed for User \"{}\"", user);
659 public void userLogout(String userName) {
660 // TODO: if user was authenticated through AAA server, send
661 // Acct-Status-Type=stop message to server with logout as reason
662 removeUserFromActiveList(userName);
663 logger.trace("User \"{}\" logged out", userName);
667 * This function will get called by http session mgr when session times out
670 public void userTimedOut(String userName) {
671 // TODO: if user was authenticated through AAA server, send
672 // Acct-Status-Type=stop message to server with timeout as reason
673 removeUserFromActiveList(userName);
674 logger.trace("User \"{}\" timed out", userName);
678 public String getAccessDate(String user) {
679 return this.activeUsers.get(user).getAccessDate();
683 public synchronized Map<String, List<String>> getUserLoggedIn() {
684 Map<String, List<String>> loggedInList = new HashMap<String, List<String>>();
685 for (Map.Entry<String, AuthenticatedUser> user : activeUsers.entrySet()) {
686 String userNameShow = user.getKey();
687 loggedInList.put(userNameShow, user.getValue().getUserRoles());
692 public void _umAddUser(CommandInterpreter ci) {
693 String userName = ci.nextArgument();
694 String password = ci.nextArgument();
695 String role = ci.nextArgument();
697 List<String> roles = new ArrayList<String>();
698 while (role != null) {
699 if (!role.trim().isEmpty()) {
702 role = ci.nextArgument();
705 if (userName == null || userName.trim().isEmpty() || password == null || password.trim().isEmpty()
706 || roles.isEmpty()) {
707 ci.println("Invalid Arguments");
708 ci.println("umAddUser <user_name> <password> <user_role>");
711 ci.print(this.addLocalUser(new UserConfig(userName, password, roles)));
714 public void _umRemUser(CommandInterpreter ci) {
715 String userName = ci.nextArgument();
717 if (userName == null || userName.trim().isEmpty()) {
718 ci.println("Invalid Arguments");
719 ci.println("umRemUser <user_name>");
722 UserConfig target = localUserConfigList.get(userName);
723 if (target == null) {
724 ci.println("User not found");
727 ci.println(this.removeLocalUser(target));
730 public void _umGetUsers(CommandInterpreter ci) {
731 for (UserConfig conf : this.getLocalUserList()) {
732 ci.println(conf.getUser() + " " + conf.getRoles());
736 public void _addAAAServer(CommandInterpreter ci) {
737 String server = ci.nextArgument();
738 String secret = ci.nextArgument();
739 String protocol = ci.nextArgument();
741 if (server == null || secret == null || protocol == null) {
742 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
745 ServerConfig s = new ServerConfig(server, secret, protocol);
749 public void _removeAAAServer(CommandInterpreter ci) {
750 String server = ci.nextArgument();
751 String secret = ci.nextArgument();
752 String protocol = ci.nextArgument();
754 if (server == null || secret == null || protocol == null) {
755 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
758 ServerConfig s = new ServerConfig(server, secret, protocol);
762 public void _printAAAServers(CommandInterpreter ci) {
763 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
764 ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
769 public String getHelp() {
770 StringBuffer help = new StringBuffer();
771 return help.toString();
774 void setClusterGlobalService(IClusterGlobalServices s) {
775 logger.debug("Cluster Service Global set");
776 this.clusterGlobalService = s;
779 void unsetClusterGlobalService(IClusterGlobalServices s) {
780 if (this.clusterGlobalService == s) {
781 logger.debug("Cluster Service Global removed!");
782 this.clusterGlobalService = null;
786 public void setConfigurationService(IConfigurationService service) {
787 logger.trace("Got configuration service set request {}", service);
788 this.configurationService = service;
791 public void unsetConfigurationService(IConfigurationService service) {
792 logger.trace("Got configuration service UNset request");
793 this.configurationService = null;
796 void unsetContainerAuthClient(IContainerAuthorization s) {
797 if (this.containerAuthorizationClient == s) {
798 this.containerAuthorizationClient = null;
802 void setContainerAuthClient(IContainerAuthorization s) {
803 this.containerAuthorizationClient = s;
806 void setAppAuthClient(IResourceAuthorization s) {
807 this.applicationAuthorizationClients.add(s);
810 void unsetAppAuthClient(IResourceAuthorization s) {
811 this.applicationAuthorizationClients.remove(s);
815 * Function called by the dependency manager when all the required
816 * dependencies are satisfied
823 * Function called by the dependency manager when at least one dependency
824 * become unsatisfied or when the component is shutting down because for
825 * example bundle is being stopped.
832 * Function called by dependency manager after "init ()" is called and after
833 * the services provided by the class are registered in the service registry
837 authProviders = new ConcurrentHashMap<String, IAAAProvider>();
838 // Instantiate cluster synced variables
842 // Read startup configuration and populate databases
843 loadConfigurations();
845 // Check if a password recovery was triggered for default network admin user
846 checkPasswordRecovery();
848 // Make sure default Network Admin account is there
849 checkDefaultNetworkAdmin();
851 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
852 bundleContext.registerService(CommandProvider.class.getName(), this, null);
856 * Function called by the dependency manager before the services exported by
857 * the component are unregistered, this will be followed by a "destroy ()"
865 public List<String> getUserRoles(String userName) {
866 List<String> roles = null;
867 if (userName != null) {
869 * First look in active users then in local configured users,
870 * finally in local authorized users
872 if (activeUsers.containsKey(userName)) {
873 roles = activeUsers.get(userName).getUserRoles();
874 } else if (localUserConfigList.containsKey(userName)) {
875 roles = localUserConfigList.get(userName).getRoles();
876 } else if (authorizationConfList.containsKey(userName)) {
877 roles = authorizationConfList.get(userName).getRoles();
880 return (roles == null) ? new ArrayList<String>(0) : roles;
884 public UserLevel getUserLevel(String username) {
885 // Returns the highest controller user level for the passed user
886 List<String> rolesNames = getUserRoles(username);
888 if (rolesNames.isEmpty()) {
889 return UserLevel.NOUSER;
892 // Check against the well known controller roles first
893 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
894 return UserLevel.SYSTEMADMIN;
896 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
897 return UserLevel.NETWORKADMIN;
899 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
900 return UserLevel.NETWORKOPERATOR;
902 // Check if container user now
903 if (containerAuthorizationClient != null) {
904 for (String roleName : rolesNames) {
905 if (containerAuthorizationClient.isApplicationRole(roleName)) {
906 return UserLevel.CONTAINERUSER;
910 // Finally check if application user
911 if (applicationAuthorizationClients != null) {
912 for (String roleName : rolesNames) {
913 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
914 if (client.isApplicationRole(roleName)) {
915 return UserLevel.APPUSER;
920 return UserLevel.NOUSER;
925 public List<UserLevel> getUserLevels(String username) {
926 // Returns the controller user levels for the passed user
927 List<String> rolesNames = getUserRoles(username);
928 List<UserLevel> levels = new ArrayList<UserLevel>();
930 if (rolesNames.isEmpty()) {
934 // Check against the well known controller roles first
935 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
936 levels.add(UserLevel.SYSTEMADMIN);
938 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
939 levels.add(UserLevel.NETWORKADMIN);
941 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
942 levels.add(UserLevel.NETWORKOPERATOR);
944 // Check if container user now
945 if (containerAuthorizationClient != null) {
946 for (String roleName : rolesNames) {
947 if (containerAuthorizationClient.isApplicationRole(roleName)) {
948 levels.add(UserLevel.CONTAINERUSER);
953 // Finally check if application user
954 if (applicationAuthorizationClients != null) {
955 for (String roleName : rolesNames) {
956 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
957 if (client.isApplicationRole(roleName)) {
958 levels.add(UserLevel.APPUSER);
968 public Status saveConfiguration() {
969 boolean success = true;
970 Status ret = saveLocalUserList();
971 if (!ret.isSuccess()) {
974 ret = saveAAAServerList();
975 if (!ret.isSuccess()) {
978 ret = saveAuthorizationList();
979 if (!ret.isSuccess()) {
984 return new Status(StatusCode.SUCCESS);
987 return new Status(StatusCode.INTERNALERROR, "Failed to save user configurations");
991 public UserDetails loadUserByUsername(String username)
992 throws UsernameNotFoundException {
993 AuthenticatedUser user = activeUsers.get(username);
996 boolean enabled = true;
997 boolean accountNonExpired = true;
998 boolean credentialsNonExpired = true;
999 boolean accountNonLocked = true;
1001 return new User(username, localUserConfigList.get(username)
1002 .getPassword(), enabled, accountNonExpired,
1003 credentialsNonExpired, accountNonLocked,
1004 user.getGrantedAuthorities(getUserLevel(username)));
1006 throw new UsernameNotFoundException("User not found " + username);
1011 public boolean supports(Class<?> authentication) {
1012 return UsernamePasswordAuthenticationToken.class
1013 .isAssignableFrom(authentication);
1018 public SecurityContextRepository getSecurityContextRepo() {
1019 return securityContextRepo;
1022 public void setSecurityContextRepo(
1023 SecurityContextRepository securityContextRepo) {
1024 this.securityContextRepo = securityContextRepo;
1028 public Authentication authenticate(Authentication authentication)
1029 throws AuthenticationException {
1031 if (StringUtils.isBlank((String) authentication.getCredentials())
1032 || StringUtils.isBlank((String) authentication.getPrincipal())) {
1033 throw new BadCredentialsException(
1034 "Username or credentials did not match");
1037 AuthResultEnum result = authenticate(
1038 (String) authentication.getPrincipal(),
1039 (String) authentication.getCredentials());
1040 if (result.equals(AuthResultEnum.AUTHOR_PASS)
1041 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
1042 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
1044 AuthenticatedUser user = activeUsers.get(authentication
1045 .getPrincipal().toString());
1048 throw new AuthenticationServiceException(
1049 "Authentication Failure");
1052 authentication = new UsernamePasswordAuthenticationToken(
1053 authentication.getPrincipal(),
1054 authentication.getCredentials(),
1055 user.getGrantedAuthorities(getUserLevel(authentication
1057 return authentication;
1060 throw new BadCredentialsException(
1061 "Username or credentials did not match");
1066 // Following are setters for use in unit testing
1067 void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1069 this.localUserConfigList = ucl;
1073 void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1075 this.remoteServerConfigList = scl;
1079 void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1081 this.authorizationConfList = acl;
1085 void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1087 this.activeUsers = au;
1091 void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1093 this.authProviders = ap;
1098 public ISessionManager getSessionManager() {
1099 return this.sessionMgr;
1102 public void setSessionMgr(ISessionManager sessionMgr) {
1103 this.sessionMgr = sessionMgr;
1107 public String getPassword(String username) {
1108 return localUserConfigList.get(username).getPassword();
1112 public boolean isRoleInUse(String role) {
1113 if (role == null || role.isEmpty()) {
1116 // Check against controller roles
1117 if (role.equals(UserLevel.SYSTEMADMIN.toString())
1118 || role.equals(UserLevel.NETWORKADMIN.toString())
1119 || role.equals(UserLevel.NETWORKOPERATOR.toString())) {
1122 // Check if container roles
1123 if (containerAuthorizationClient != null) {
1124 if (containerAuthorizationClient.isApplicationRole(role)) {
1128 // Finally if application role
1129 if (applicationAuthorizationClients != null) {
1130 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
1131 if (client.isApplicationRole(role)) {