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.IConfigurationAware;
35 import org.opendaylight.controller.containermanager.IContainerAuthorization;
36 import org.opendaylight.controller.sal.authorization.AuthResultEnum;
37 import org.opendaylight.controller.sal.authorization.IResourceAuthorization;
38 import org.opendaylight.controller.sal.authorization.UserLevel;
39 import org.opendaylight.controller.sal.utils.StatusCode;
40 import org.opendaylight.controller.sal.utils.GlobalConstants;
41 import org.opendaylight.controller.sal.utils.IObjectReader;
42 import org.opendaylight.controller.sal.utils.ObjectReader;
43 import org.opendaylight.controller.sal.utils.ObjectWriter;
44 import org.opendaylight.controller.sal.utils.Status;
45 import org.opendaylight.controller.usermanager.AuthResponse;
46 import org.opendaylight.controller.usermanager.AuthenticatedUser;
47 import org.opendaylight.controller.usermanager.AuthorizationConfig;
48 import org.opendaylight.controller.usermanager.IAAAProvider;
49 import org.opendaylight.controller.usermanager.ISessionManager;
50 import org.opendaylight.controller.usermanager.IUserManager;
51 import org.opendaylight.controller.usermanager.ServerConfig;
52 import org.opendaylight.controller.usermanager.UserConfig;
53 import org.opendaylight.controller.usermanager.security.SessionManager;
54 import org.opendaylight.controller.usermanager.security.UserSecurityContextRepository;
56 import org.osgi.framework.BundleContext;
57 import org.osgi.framework.FrameworkUtil;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60 import org.springframework.security.authentication.AuthenticationProvider;
61 import org.springframework.security.authentication.AuthenticationServiceException;
62 import org.springframework.security.authentication.BadCredentialsException;
63 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
64 import org.springframework.security.core.Authentication;
65 import org.springframework.security.core.AuthenticationException;
66 import org.springframework.security.core.userdetails.User;
67 import org.springframework.security.core.userdetails.UserDetails;
68 import org.springframework.security.core.userdetails.UsernameNotFoundException;
69 import org.springframework.security.web.context.SecurityContextRepository;
72 * The internal implementation of the User Manager.
74 public class UserManager implements IUserManager, IObjectReader,
75 IConfigurationAware, CommandProvider, AuthenticationProvider {
76 private static final Logger logger = LoggerFactory.getLogger(UserManager.class);
77 private static final String DEFAULT_ADMIN = "admin";
78 private static final String DEFAULT_ADMIN_PASSWORD = "admin";
79 private static final String DEFAULT_ADMIN_ROLE = UserLevel.NETWORKADMIN.toString();
80 private static final String ROOT = GlobalConstants.STARTUPHOME.toString();
81 private static final String USERS_FILE_NAME = ROOT + "users.conf";
82 private static final String SERVERS_FILE_NAME = ROOT + "servers.conf";
83 private static final String AUTH_FILE_NAME = ROOT + "authorization.conf";
84 private static final String RECOVERY_FILE = ROOT + "NETWORK_ADMIN_PASSWORD_RECOVERY";
85 private ConcurrentMap<String, UserConfig> localUserConfigList;
86 private ConcurrentMap<String, ServerConfig> remoteServerConfigList;
87 // local authorization info for remotely authenticated users
88 private ConcurrentMap<String, AuthorizationConfig> authorizationConfList;
89 private ConcurrentMap<String, AuthenticatedUser> activeUsers;
90 private ConcurrentMap<String, IAAAProvider> authProviders;
91 private IClusterGlobalServices clusterGlobalService = null;
92 private SecurityContextRepository securityContextRepo = new UserSecurityContextRepository();
93 private IContainerAuthorization containerAuthorizationClient;
94 private Set<IResourceAuthorization> applicationAuthorizationClients;
95 private ISessionManager sessionMgr = new SessionManager();
97 public boolean addAAAProvider(IAAAProvider provider) {
98 if (provider == null || provider.getName() == null
99 || provider.getName().trim().isEmpty()) {
102 if (authProviders.get(provider.getName()) != null) {
106 authProviders.put(provider.getName(), provider);
110 public void removeAAAProvider(IAAAProvider provider) {
111 authProviders.remove(provider.getName());
114 public IAAAProvider getAAAProvider(String name) {
115 return authProviders.get(name);
119 public Set<String> getAAAProviderNames() {
120 return authProviders.keySet();
123 private void allocateCaches() {
124 this.applicationAuthorizationClients = Collections.synchronizedSet(new HashSet<IResourceAuthorization>());
125 if (clusterGlobalService == null) {
126 logger.error("un-initialized clusterGlobalService, can't create cache");
131 clusterGlobalService.createCache("usermanager.localUserConfigList",
132 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
134 clusterGlobalService.createCache(
135 "usermanager.remoteServerConfigList",
136 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
138 clusterGlobalService.createCache(
139 "usermanager.authorizationConfList",
140 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
142 clusterGlobalService.createCache("usermanager.activeUsers",
143 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
144 } catch (CacheConfigException cce) {
145 logger.error("Cache configuration invalid - check cache mode");
146 } catch (CacheExistException ce) {
147 logger.debug("Skipping cache creation as already present");
151 @SuppressWarnings({ "unchecked" })
152 private void retrieveCaches() {
153 if (clusterGlobalService == null) {
154 logger.error("un-initialized clusterService, can't retrieve cache");
158 activeUsers = (ConcurrentMap<String, AuthenticatedUser>) clusterGlobalService
159 .getCache("usermanager.activeUsers");
160 if (activeUsers == null) {
161 logger.error("Failed to get cache for activeUsers");
164 localUserConfigList = (ConcurrentMap<String, UserConfig>) clusterGlobalService
165 .getCache("usermanager.localUserConfigList");
166 if (localUserConfigList == null) {
167 logger.error("Failed to get cache for localUserConfigList");
170 remoteServerConfigList = (ConcurrentMap<String, ServerConfig>) clusterGlobalService
171 .getCache("usermanager.remoteServerConfigList");
172 if (remoteServerConfigList == null) {
173 logger.error("Failed to get cache for remoteServerConfigList");
176 authorizationConfList = (ConcurrentMap<String, AuthorizationConfig>) clusterGlobalService
177 .getCache("usermanager.authorizationConfList");
178 if (authorizationConfList == null) {
179 logger.error("Failed to get cache for authorizationConfList");
183 private void loadConfigurations() {
184 // To encode and decode user and server configuration objects
188 * Do not load local startup file if we already got the configurations
189 * synced from another cluster node
191 if (localUserConfigList.isEmpty()) {
194 if (remoteServerConfigList.isEmpty()) {
197 if (authorizationConfList.isEmpty()) {
202 private void loadSecurityKeys() {
206 private void checkDefaultNetworkAdmin() {
207 // If startup config is not there, it's old or it was deleted,
208 // need to add Default Network Admin User
209 if (!localUserConfigList.containsKey(DEFAULT_ADMIN)) {
210 List<String> roles = new ArrayList<String>(1);
211 roles.add(DEFAULT_ADMIN_ROLE);
212 localUserConfigList.put(DEFAULT_ADMIN, new UserConfig(DEFAULT_ADMIN, DEFAULT_ADMIN_PASSWORD, roles));
216 private void checkPasswordRecovery() {
217 final String fileDescription = "Default Network Administrator password recovery file";
219 FileInputStream fis = new FileInputStream(UserManager.RECOVERY_FILE);
221 * Recovery file detected, remove current default network
222 * administrator entry from local users configuration list.
223 * Warn user and delete recovery file.
225 this.localUserConfigList.remove(UserManager.DEFAULT_ADMIN);
226 logger.info("Default Network Administrator password has been reset to factory default.");
227 logger.info("Please change the default Network Administrator password as soon as possible");
228 File filePointer = new File(UserManager.RECOVERY_FILE);
229 boolean status = filePointer.delete();
231 logger.warn("Failed to delete {}", fileDescription);
233 logger.trace("{} deleted", fileDescription);
236 } catch (FileNotFoundException fnf) {
237 logger.trace("{} not present", fileDescription);
238 } catch (IOException e) {
239 logger.warn("Failed to close file stream for {}", fileDescription);
244 public AuthResultEnum authenticate(String userName, String password) {
245 IAAAProvider aaaClient;
246 AuthResponse rcResponse = null;
247 AuthenticatedUser result;
248 boolean remotelyAuthenticated = false;
249 boolean authorizationInfoIsPresent = false;
250 boolean authorized = false;
253 * Attempt remote authentication first if server is configured
255 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
256 String protocol = aaaServer.getProtocol();
257 aaaClient = this.getAAAProvider(protocol);
258 if (aaaClient != null) {
259 rcResponse = aaaClient.authService(userName, password,
260 aaaServer.getAddress(), aaaServer.getSecret());
261 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
263 "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
264 userName, aaaServer.getAddress());
265 remotelyAuthenticated = true;
267 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
269 "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
270 new Object[] { userName, aaaServer.getAddress(),
271 rcResponse.getStatus().toString() });
274 "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
275 new Object[] { userName, aaaServer.getAddress(),
276 rcResponse.getStatus().toString() });
281 if (!remotelyAuthenticated) {
282 UserConfig localUser = this.localUserConfigList.get(userName);
283 if (localUser == null) {
285 "Local Authentication Failed for User:\"{}\", Reason: "
286 + "user not found in Local Database", userName);
287 return (AuthResultEnum.AUTH_INVALID_LOC_USER);
289 rcResponse = localUser.authenticate(password);
290 if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
292 "Local Authentication Failed for User: \"{}\", Reason: {}",
293 userName, rcResponse.getStatus().toString());
295 return (rcResponse.getStatus());
297 logger.info("Local Authentication Succeeded for User: \"{}\"",
302 * Authentication succeeded
304 result = new AuthenticatedUser(userName);
307 * Extract attributes from response All the information we are
308 * interested in is in the first Cisco VSA (vendor specific attribute).
309 * Just process the first VSA and return
311 String attributes = (rcResponse.getData() != null && !rcResponse
312 .getData().isEmpty()) ? rcResponse.getData().get(0) : null;
315 * Check if the authorization information is present
317 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
320 * The AAA server was only used to perform the authentication Look for
321 * locally stored authorization info for this user If found, add the
322 * data to the rcResponse
324 if (remotelyAuthenticated && !authorizationInfoIsPresent) {
326 "No Remote Authorization Info provided by Server for User: \"{}\"",
329 "Looking for Local Authorization Info for User: \"{}\"",
332 AuthorizationConfig resource = authorizationConfList.get(userName);
333 if (resource != null) {
334 logger.info("Found Local Authorization Info for User: \"{}\"",
336 attributes = resource.getRolesString();
339 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
343 * Common response parsing for local & remote authenticated user Looking
344 * for authorized resources, detecting attributes' validity
346 if (authorizationInfoIsPresent) {
347 // Identifying the administrative role
348 result.setRoleList(attributes.split(" "));
351 logger.info("Not able to find Authorization Info for User: \"{}\"",
356 * Add profile for authenticated user
358 putUserInActiveList(userName, result);
360 logger.info("User \"{}\" authorized for the following role(s): {}",
361 userName, result.getUserRoles());
363 logger.info("User \"{}\" Not Authorized for any role ", userName);
366 return rcResponse.getStatus();
369 // Check in the attributes string whether or not authorization information
371 private boolean checkAuthorizationInfo(String attributes) {
372 return (attributes != null && !attributes.isEmpty());
375 private void putUserInActiveList(String user, AuthenticatedUser result) {
376 activeUsers.put(user, result);
379 private void removeUserFromActiveList(String user) {
380 if (!activeUsers.containsKey(user)) {
381 // as cookie persists in cache, we can get logout for unexisting
385 activeUsers.remove(user);
389 public Status saveLocalUserList() {
390 return saveLocalUserListInternal();
393 private Status saveLocalUserListInternal() {
394 ObjectWriter objWriter = new ObjectWriter();
395 return objWriter.write(new ConcurrentHashMap<String, UserConfig>(
396 localUserConfigList), USERS_FILE_NAME);
400 public Status saveAAAServerList() {
401 return saveAAAServerListInternal();
404 private Status saveAAAServerListInternal() {
405 ObjectWriter objWriter = new ObjectWriter();
406 return objWriter.write(new ConcurrentHashMap<String, ServerConfig>(
407 remoteServerConfigList), SERVERS_FILE_NAME);
411 public Status saveAuthorizationList() {
412 return saveAuthorizationListInternal();
415 private Status saveAuthorizationListInternal() {
416 ObjectWriter objWriter = new ObjectWriter();
417 return objWriter.write(
418 new ConcurrentHashMap<String, AuthorizationConfig>(
419 authorizationConfList), AUTH_FILE_NAME);
423 public Object readObject(ObjectInputStream ois)
424 throws FileNotFoundException, IOException, ClassNotFoundException {
425 // Perform the class deserialization locally, from inside the package
426 // where the class is defined
427 return ois.readObject();
430 @SuppressWarnings("unchecked")
431 private void loadUserConfig() {
432 ObjectReader objReader = new ObjectReader();
433 ConcurrentMap<String, UserConfig> confList = (ConcurrentMap<String, UserConfig>) objReader
434 .read(this, USERS_FILE_NAME);
436 if (confList == null) {
440 for (UserConfig conf : confList.values()) {
441 addRemoveLocalUserInternal(conf, false);
445 @SuppressWarnings("unchecked")
446 private void loadServerConfig() {
447 ObjectReader objReader = new ObjectReader();
448 ConcurrentMap<String, ServerConfig> confList = (ConcurrentMap<String, ServerConfig>) objReader
449 .read(this, SERVERS_FILE_NAME);
451 if (confList == null) {
455 for (ServerConfig conf : confList.values()) {
460 @SuppressWarnings("unchecked")
461 private void loadAuthConfig() {
462 ObjectReader objReader = new ObjectReader();
463 ConcurrentMap<String, AuthorizationConfig> confList = (ConcurrentMap<String, AuthorizationConfig>) objReader
464 .read(this, AUTH_FILE_NAME);
466 if (confList == null) {
470 for (AuthorizationConfig conf : confList.values()) {
476 * Interaction with GUI START
478 private Status addRemoveLocalUser(UserConfig AAAconf, boolean delete) {
479 // UserConfig Validation check
480 Status validCheck = AAAconf.validate();
481 if (!validCheck.isSuccess()) {
485 String user = AAAconf.getUser();
487 // Check default admin user
488 if (user.equals(UserManager.DEFAULT_ADMIN)) {
489 String msg = "Invalid Request: Default Network Admin User cannot be " + ((delete)? "removed" : "added");
491 return new Status(StatusCode.NOTALLOWED, msg);
494 // Check user presence/conflict
495 StatusCode statusCode = null;
496 String reason = null;
497 if (delete && !localUserConfigList.containsKey(user)) {
498 reason = "not found";
499 statusCode = StatusCode.NOTFOUND;
500 } else if (!delete && localUserConfigList.containsKey(user)) {
501 reason = "already present";
502 statusCode = StatusCode.CONFLICT;
504 if (statusCode != null) {
505 String msg = String.format("User %s %s in configuration database", user, reason);
507 return new Status(statusCode, msg);
510 return addRemoveLocalUserInternal(AAAconf, delete);
513 private Status addRemoveLocalUserInternal(UserConfig AAAconf, boolean delete) {
514 // Update Config database
516 localUserConfigList.remove(AAAconf.getUser());
518 * A user account has been removed form local database, we assume
519 * admin does not want this user to stay connected, in case he has
520 * an open session. So we clean the active list as well.
522 removeUserFromActiveList(AAAconf.getUser());
524 localUserConfigList.put(AAAconf.getUser(), AAAconf);
527 return new Status(StatusCode.SUCCESS);
530 private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
532 if (!AAAconf.isValid()) {
533 String msg = "Invalid Server configuration";
535 return new Status(StatusCode.BADREQUEST, msg);
538 // Update configuration database
540 remoteServerConfigList.remove(AAAconf.getAddress());
542 remoteServerConfigList.put(AAAconf.getAddress(), AAAconf);
545 return new Status(StatusCode.SUCCESS);
548 private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
549 Status configCheck = AAAconf.validate();
550 if (!configCheck.isSuccess()) {
551 String msg = "Invalid Authorization configuration: "
552 + configCheck.getDescription();
554 return new Status(StatusCode.BADREQUEST, msg);
557 // Update configuration database
559 authorizationConfList.remove(AAAconf.getUser());
561 authorizationConfList.put(AAAconf.getUser(), AAAconf);
564 return new Status(StatusCode.SUCCESS);
568 public Status addLocalUser(UserConfig AAAconf) {
569 return addRemoveLocalUser(AAAconf, false);
573 public Status removeLocalUser(UserConfig AAAconf) {
574 return addRemoveLocalUser(AAAconf, true);
578 public Status removeLocalUser(String userName) {
579 if (userName == null || userName.trim().isEmpty()) {
580 return new Status(StatusCode.BADREQUEST, "Invalid user name");
583 if (!localUserConfigList.containsKey(userName)) {
584 return new Status(StatusCode.NOTFOUND, "User does not exist");
587 return addRemoveLocalUser(localUserConfigList.get(userName), true);
591 public Status addAAAServer(ServerConfig AAAconf) {
592 return addRemoveAAAServer(AAAconf, false);
596 public Status removeAAAServer(ServerConfig AAAconf) {
597 return addRemoveAAAServer(AAAconf, true);
601 public Status addAuthInfo(AuthorizationConfig AAAconf) {
602 return addRemoveAuthInfo(AAAconf, false);
606 public Status removeAuthInfo(AuthorizationConfig AAAconf) {
607 return addRemoveAuthInfo(AAAconf, true);
611 public List<UserConfig> getLocalUserList() {
612 return new ArrayList<UserConfig>(localUserConfigList.values());
616 public List<ServerConfig> getAAAServerList() {
617 return new ArrayList<ServerConfig>(remoteServerConfigList.values());
621 public List<AuthorizationConfig> getAuthorizationList() {
622 return new ArrayList<AuthorizationConfig>(
623 authorizationConfList.values());
627 public Status changeLocalUserPassword(String user, String curPassword, String newPassword) {
628 UserConfig targetConfigEntry = null;
630 // update configuration entry
631 targetConfigEntry = localUserConfigList.get(user);
632 if (targetConfigEntry == null) {
633 return new Status(StatusCode.NOTFOUND, "User not found");
635 Status status = targetConfigEntry.update(curPassword, newPassword, null);
636 if (!status.isSuccess()) {
639 // Trigger cluster update
640 localUserConfigList.put(user, targetConfigEntry);
642 logger.info("Password changed for User \"{}\"", user);
648 public void userLogout(String userName) {
649 // TODO: if user was authenticated through AAA server, send
650 // Acct-Status-Type=stop message to server with logout as reason
651 removeUserFromActiveList(userName);
652 logger.info("User \"{}\" logged out", userName);
656 * This function will get called by http session mgr when session times out
659 public void userTimedOut(String userName) {
660 // TODO: if user was authenticated through AAA server, send
661 // Acct-Status-Type=stop message to server with timeout as reason
662 removeUserFromActiveList(userName);
663 logger.info("User \"{}\" timed out", userName);
667 public String getAccessDate(String user) {
668 return this.activeUsers.get(user).getAccessDate();
672 public synchronized Map<String, List<String>> getUserLoggedIn() {
673 Map<String, List<String>> loggedInList = new HashMap<String, List<String>>();
674 for (Map.Entry<String, AuthenticatedUser> user : activeUsers.entrySet()) {
675 String userNameShow = user.getKey();
676 loggedInList.put(userNameShow, user.getValue().getUserRoles());
681 public void _umAddUser(CommandInterpreter ci) {
682 String userName = ci.nextArgument();
683 String password = ci.nextArgument();
684 String role = ci.nextArgument();
686 List<String> roles = new ArrayList<String>();
687 while (role != null) {
688 if (!role.trim().isEmpty()) {
691 role = ci.nextArgument();
694 if (userName == null || userName.trim().isEmpty() || password == null || password.trim().isEmpty()
695 || roles.isEmpty()) {
696 ci.println("Invalid Arguments");
697 ci.println("umAddUser <user_name> <password> <user_role>");
700 ci.print(this.addLocalUser(new UserConfig(userName, password, roles)));
703 public void _umRemUser(CommandInterpreter ci) {
704 String userName = ci.nextArgument();
706 if (userName == null || userName.trim().isEmpty()) {
707 ci.println("Invalid Arguments");
708 ci.println("umRemUser <user_name>");
711 UserConfig target = localUserConfigList.get(userName);
712 if (target == null) {
713 ci.println("User not found");
716 ci.println(this.removeLocalUser(target));
719 public void _umGetUsers(CommandInterpreter ci) {
720 for (UserConfig conf : this.getLocalUserList()) {
721 ci.println(conf.getUser() + " " + conf.getRoles());
725 public void _addAAAServer(CommandInterpreter ci) {
726 String server = ci.nextArgument();
727 String secret = ci.nextArgument();
728 String protocol = ci.nextArgument();
730 if (server == null || secret == null || protocol == null) {
731 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
734 ServerConfig s = new ServerConfig(server, secret, protocol);
738 public void _removeAAAServer(CommandInterpreter ci) {
739 String server = ci.nextArgument();
740 String secret = ci.nextArgument();
741 String protocol = ci.nextArgument();
743 if (server == null || secret == null || protocol == null) {
744 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
747 ServerConfig s = new ServerConfig(server, secret, protocol);
751 public void _printAAAServers(CommandInterpreter ci) {
752 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
753 ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
758 public String getHelp() {
759 StringBuffer help = new StringBuffer();
760 return help.toString();
763 void setClusterGlobalService(IClusterGlobalServices s) {
764 logger.debug("Cluster Service Global set");
765 this.clusterGlobalService = s;
768 void unsetClusterGlobalService(IClusterGlobalServices s) {
769 if (this.clusterGlobalService == s) {
770 logger.debug("Cluster Service Global removed!");
771 this.clusterGlobalService = null;
775 void unsetContainerAuthClient(IContainerAuthorization s) {
776 if (this.containerAuthorizationClient == s) {
777 this.containerAuthorizationClient = null;
781 void setContainerAuthClient(IContainerAuthorization s) {
782 this.containerAuthorizationClient = s;
785 void setAppAuthClient(IResourceAuthorization s) {
786 this.applicationAuthorizationClients.add(s);
789 void unsetAppAuthClient(IResourceAuthorization s) {
790 this.applicationAuthorizationClients.remove(s);
794 * Function called by the dependency manager when all the required
795 * dependencies are satisfied
802 * Function called by the dependency manager when at least one dependency
803 * become unsatisfied or when the component is shutting down because for
804 * example bundle is being stopped.
811 * Function called by dependency manager after "init ()" is called and after
812 * the services provided by the class are registered in the service registry
816 authProviders = new ConcurrentHashMap<String, IAAAProvider>();
817 // Instantiate cluster synced variables
821 // Read startup configuration and populate databases
822 loadConfigurations();
824 // Check if a password recovery was triggered for default network admin user
825 checkPasswordRecovery();
827 // Make sure default Network Admin account is there
828 checkDefaultNetworkAdmin();
830 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
831 bundleContext.registerService(CommandProvider.class.getName(), this, null);
835 * Function called by the dependency manager before the services exported by
836 * the component are unregistered, this will be followed by a "destroy ()"
844 public List<String> getUserRoles(String userName) {
845 List<String> roles = null;
846 if (userName != null) {
848 * First look in active users then in local configured users,
849 * finally in local authorized users
851 if (activeUsers.containsKey(userName)) {
852 roles = activeUsers.get(userName).getUserRoles();
853 } else if (localUserConfigList.containsKey(userName)) {
854 roles = localUserConfigList.get(userName).getRoles();
855 } else if (authorizationConfList.containsKey(userName)) {
856 roles = authorizationConfList.get(userName).getRoles();
859 return (roles == null) ? new ArrayList<String>(0) : roles;
863 public UserLevel getUserLevel(String username) {
864 // Returns the highest controller user level for the passed user
865 List<String> rolesNames = getUserRoles(username);
867 if (rolesNames.isEmpty()) {
868 return UserLevel.NOUSER;
871 // Check against the well known controller roles first
872 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
873 return UserLevel.SYSTEMADMIN;
875 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
876 return UserLevel.NETWORKADMIN;
878 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
879 return UserLevel.NETWORKOPERATOR;
881 // Check if container user now
882 if (containerAuthorizationClient != null) {
883 for (String roleName : rolesNames) {
884 if (containerAuthorizationClient.isApplicationRole(roleName)) {
885 return UserLevel.CONTAINERUSER;
889 // Finally check if application user
890 if (applicationAuthorizationClients != null) {
891 for (String roleName : rolesNames) {
892 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
893 if (client.isApplicationRole(roleName)) {
894 return UserLevel.APPUSER;
899 return UserLevel.NOUSER;
904 public List<UserLevel> getUserLevels(String username) {
905 // Returns the controller user levels for the passed user
906 List<String> rolesNames = getUserRoles(username);
907 List<UserLevel> levels = new ArrayList<UserLevel>();
909 if (rolesNames.isEmpty()) {
913 // Check against the well known controller roles first
914 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
915 levels.add(UserLevel.SYSTEMADMIN);
917 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
918 levels.add(UserLevel.NETWORKADMIN);
920 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
921 levels.add(UserLevel.NETWORKOPERATOR);
923 // Check if container user now
924 if (containerAuthorizationClient != null) {
925 for (String roleName : rolesNames) {
926 if (containerAuthorizationClient.isApplicationRole(roleName)) {
927 levels.add(UserLevel.CONTAINERUSER);
932 // Finally check if application user
933 if (applicationAuthorizationClients != null) {
934 for (String roleName : rolesNames) {
935 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
936 if (client.isApplicationRole(roleName)) {
937 levels.add(UserLevel.APPUSER);
947 public Status saveConfiguration() {
948 boolean success = true;
949 Status ret = saveLocalUserList();
950 if (!ret.isSuccess()) {
953 ret = saveAAAServerList();
954 if (!ret.isSuccess()) {
957 ret = saveAuthorizationList();
958 if (!ret.isSuccess()) {
963 return new Status(StatusCode.SUCCESS);
966 return new Status(StatusCode.INTERNALERROR, "Failed to save user configurations");
970 public UserDetails loadUserByUsername(String username)
971 throws UsernameNotFoundException {
972 AuthenticatedUser user = activeUsers.get(username);
975 boolean enabled = true;
976 boolean accountNonExpired = true;
977 boolean credentialsNonExpired = true;
978 boolean accountNonLocked = true;
980 return new User(username, localUserConfigList.get(username)
981 .getPassword(), enabled, accountNonExpired,
982 credentialsNonExpired, accountNonLocked,
983 user.getGrantedAuthorities(getUserLevel(username)));
985 throw new UsernameNotFoundException("User not found " + username);
990 public boolean supports(Class<?> authentication) {
991 return UsernamePasswordAuthenticationToken.class
992 .isAssignableFrom(authentication);
997 public SecurityContextRepository getSecurityContextRepo() {
998 return securityContextRepo;
1001 public void setSecurityContextRepo(
1002 SecurityContextRepository securityContextRepo) {
1003 this.securityContextRepo = securityContextRepo;
1007 public Authentication authenticate(Authentication authentication)
1008 throws AuthenticationException {
1010 if (StringUtils.isBlank((String) authentication.getCredentials())
1011 || StringUtils.isBlank((String) authentication.getPrincipal())) {
1012 throw new BadCredentialsException(
1013 "Username or credentials did not match");
1016 AuthResultEnum result = authenticate(
1017 (String) authentication.getPrincipal(),
1018 (String) authentication.getCredentials());
1019 if (result.equals(AuthResultEnum.AUTHOR_PASS)
1020 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
1021 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
1023 AuthenticatedUser user = activeUsers.get(authentication
1024 .getPrincipal().toString());
1027 throw new AuthenticationServiceException(
1028 "Authentication Failure");
1031 authentication = new UsernamePasswordAuthenticationToken(
1032 authentication.getPrincipal(),
1033 authentication.getCredentials(),
1034 user.getGrantedAuthorities(getUserLevel(authentication
1036 return authentication;
1039 throw new BadCredentialsException(
1040 "Username or credentials did not match");
1045 // Following are setters for use in unit testing
1046 void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1048 this.localUserConfigList = ucl;
1052 void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1054 this.remoteServerConfigList = scl;
1058 void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1060 this.authorizationConfList = acl;
1064 void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1066 this.activeUsers = au;
1070 void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1072 this.authProviders = ap;
1077 public ISessionManager getSessionManager() {
1078 return this.sessionMgr;
1081 public void setSessionMgr(ISessionManager sessionMgr) {
1082 this.sessionMgr = sessionMgr;
1086 public String getPassword(String username) {
1087 return localUserConfigList.get(username).getPassword();
1091 public boolean isRoleInUse(String role) {
1092 if (role == null || role.isEmpty()) {
1095 // Check against controller roles
1096 if (role.equals(UserLevel.SYSTEMADMIN.toString())
1097 || role.equals(UserLevel.NETWORKADMIN.toString())
1098 || role.equals(UserLevel.NETWORKOPERATOR.toString())) {
1101 // Check if container roles
1102 if (containerAuthorizationClient != null) {
1103 if (containerAuthorizationClient.isApplicationRole(role)) {
1107 // Finally if application role
1108 if (applicationAuthorizationClients != null) {
1109 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
1110 if (client.isApplicationRole(role)) {