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() {
208 * If startup config is not there, it's old or it was deleted or if a
209 * password recovery was run, need to add Default Network Admin User
211 if (!localUserConfigList.containsKey(DEFAULT_ADMIN)) {
212 List<String> roles = new ArrayList<String>(1);
213 roles.add(DEFAULT_ADMIN_ROLE);
214 // Need to skip the strong password check for the default admin
215 UserConfig defaultAdmin = UserConfig.getUncheckedUserConfig(UserManager.DEFAULT_ADMIN,
216 UserManager.DEFAULT_ADMIN_PASSWORD, roles);
217 localUserConfigList.put(UserManager.DEFAULT_ADMIN, defaultAdmin);
221 private void checkPasswordRecovery() {
222 final String fileDescription = "Default Network Administrator password recovery file";
224 FileInputStream fis = new FileInputStream(UserManager.RECOVERY_FILE);
226 * Recovery file detected, remove current default network
227 * administrator entry from local users configuration list.
228 * Warn user and delete recovery file.
230 this.localUserConfigList.remove(UserManager.DEFAULT_ADMIN);
231 logger.info("Default Network Administrator password has been reset to factory default.");
232 logger.info("Please change the default Network Administrator password as soon as possible");
233 File filePointer = new File(UserManager.RECOVERY_FILE);
234 boolean status = filePointer.delete();
236 logger.warn("Failed to delete {}", fileDescription);
238 logger.trace("{} deleted", fileDescription);
241 } catch (FileNotFoundException fnf) {
242 logger.trace("{} not present", fileDescription);
243 } catch (IOException e) {
244 logger.warn("Failed to close file stream for {}", fileDescription);
249 public AuthResultEnum authenticate(String userName, String password) {
250 IAAAProvider aaaClient;
251 AuthResponse rcResponse = null;
252 AuthenticatedUser result;
253 boolean remotelyAuthenticated = false;
254 boolean authorizationInfoIsPresent = false;
255 boolean authorized = false;
258 * Attempt remote authentication first if server is configured
260 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
261 String protocol = aaaServer.getProtocol();
262 aaaClient = this.getAAAProvider(protocol);
263 if (aaaClient != null) {
264 rcResponse = aaaClient.authService(userName, password,
265 aaaServer.getAddress(), aaaServer.getSecret());
266 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
268 "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
269 userName, aaaServer.getAddress());
270 remotelyAuthenticated = true;
272 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
274 "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
275 new Object[] { userName, aaaServer.getAddress(),
276 rcResponse.getStatus().toString() });
279 "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
280 new Object[] { userName, aaaServer.getAddress(),
281 rcResponse.getStatus().toString() });
286 if (!remotelyAuthenticated) {
287 UserConfig localUser = this.localUserConfigList.get(userName);
288 if (localUser == null) {
290 "Local Authentication Failed for User:\"{}\", Reason: "
291 + "user not found in Local Database", userName);
292 return (AuthResultEnum.AUTH_INVALID_LOC_USER);
294 rcResponse = localUser.authenticate(password);
295 if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
297 "Local Authentication Failed for User: \"{}\", Reason: {}",
298 userName, rcResponse.getStatus().toString());
300 return (rcResponse.getStatus());
302 logger.info("Local Authentication Succeeded for User: \"{}\"",
307 * Authentication succeeded
309 result = new AuthenticatedUser(userName);
312 * Extract attributes from response All the information we are
313 * interested in is in the first Cisco VSA (vendor specific attribute).
314 * Just process the first VSA and return
316 String attributes = (rcResponse.getData() != null && !rcResponse
317 .getData().isEmpty()) ? rcResponse.getData().get(0) : null;
320 * Check if the authorization information is present
322 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
325 * The AAA server was only used to perform the authentication Look for
326 * locally stored authorization info for this user If found, add the
327 * data to the rcResponse
329 if (remotelyAuthenticated && !authorizationInfoIsPresent) {
331 "No Remote Authorization Info provided by Server for User: \"{}\"",
334 "Looking for Local Authorization Info for User: \"{}\"",
337 AuthorizationConfig resource = authorizationConfList.get(userName);
338 if (resource != null) {
339 logger.info("Found Local Authorization Info for User: \"{}\"",
341 attributes = resource.getRolesString();
344 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
348 * Common response parsing for local & remote authenticated user Looking
349 * for authorized resources, detecting attributes' validity
351 if (authorizationInfoIsPresent) {
352 // Identifying the administrative role
353 result.setRoleList(attributes.split(" "));
356 logger.info("Not able to find Authorization Info for User: \"{}\"",
361 * Add profile for authenticated user
363 putUserInActiveList(userName, result);
365 logger.info("User \"{}\" authorized for the following role(s): {}",
366 userName, result.getUserRoles());
368 logger.info("User \"{}\" Not Authorized for any role ", userName);
371 return rcResponse.getStatus();
374 // Check in the attributes string whether or not authorization information
376 private boolean checkAuthorizationInfo(String attributes) {
377 return (attributes != null && !attributes.isEmpty());
380 private void putUserInActiveList(String user, AuthenticatedUser result) {
381 activeUsers.put(user, result);
384 private void removeUserFromActiveList(String user) {
385 if (!activeUsers.containsKey(user)) {
386 // as cookie persists in cache, we can get logout for unexisting
390 activeUsers.remove(user);
394 public Status saveLocalUserList() {
395 return saveLocalUserListInternal();
398 private Status saveLocalUserListInternal() {
399 ObjectWriter objWriter = new ObjectWriter();
400 return objWriter.write(new ConcurrentHashMap<String, UserConfig>(
401 localUserConfigList), USERS_FILE_NAME);
405 public Status saveAAAServerList() {
406 return saveAAAServerListInternal();
409 private Status saveAAAServerListInternal() {
410 ObjectWriter objWriter = new ObjectWriter();
411 return objWriter.write(new ConcurrentHashMap<String, ServerConfig>(
412 remoteServerConfigList), SERVERS_FILE_NAME);
416 public Status saveAuthorizationList() {
417 return saveAuthorizationListInternal();
420 private Status saveAuthorizationListInternal() {
421 ObjectWriter objWriter = new ObjectWriter();
422 return objWriter.write(
423 new ConcurrentHashMap<String, AuthorizationConfig>(
424 authorizationConfList), AUTH_FILE_NAME);
428 public Object readObject(ObjectInputStream ois)
429 throws FileNotFoundException, IOException, ClassNotFoundException {
430 // Perform the class deserialization locally, from inside the package
431 // where the class is defined
432 return ois.readObject();
435 @SuppressWarnings("unchecked")
436 private void loadUserConfig() {
437 ObjectReader objReader = new ObjectReader();
438 ConcurrentMap<String, UserConfig> confList = (ConcurrentMap<String, UserConfig>) objReader
439 .read(this, USERS_FILE_NAME);
441 if (confList == null) {
445 for (UserConfig conf : confList.values()) {
446 addRemoveLocalUserInternal(conf, false);
450 @SuppressWarnings("unchecked")
451 private void loadServerConfig() {
452 ObjectReader objReader = new ObjectReader();
453 ConcurrentMap<String, ServerConfig> confList = (ConcurrentMap<String, ServerConfig>) objReader
454 .read(this, SERVERS_FILE_NAME);
456 if (confList == null) {
460 for (ServerConfig conf : confList.values()) {
465 @SuppressWarnings("unchecked")
466 private void loadAuthConfig() {
467 ObjectReader objReader = new ObjectReader();
468 ConcurrentMap<String, AuthorizationConfig> confList = (ConcurrentMap<String, AuthorizationConfig>) objReader
469 .read(this, AUTH_FILE_NAME);
471 if (confList == null) {
475 for (AuthorizationConfig conf : confList.values()) {
481 * Interaction with GUI START
483 private Status addRemoveLocalUser(UserConfig AAAconf, boolean delete) {
484 // UserConfig Validation check
485 Status validCheck = AAAconf.validate();
486 if (!validCheck.isSuccess()) {
490 String user = AAAconf.getUser();
492 // Check default admin user
493 if (user.equals(UserManager.DEFAULT_ADMIN)) {
494 String msg = "Invalid Request: Default Network Admin User cannot be " + ((delete)? "removed" : "added");
496 return new Status(StatusCode.NOTALLOWED, msg);
499 // Check user presence/conflict
500 StatusCode statusCode = null;
501 String reason = null;
502 if (delete && !localUserConfigList.containsKey(user)) {
503 reason = "not found";
504 statusCode = StatusCode.NOTFOUND;
505 } else if (!delete && localUserConfigList.containsKey(user)) {
506 reason = "already present";
507 statusCode = StatusCode.CONFLICT;
509 if (statusCode != null) {
510 String msg = String.format("User %s %s in configuration database", user, reason);
512 return new Status(statusCode, msg);
515 return addRemoveLocalUserInternal(AAAconf, delete);
518 private Status addRemoveLocalUserInternal(UserConfig AAAconf, boolean delete) {
519 // Update Config database
521 localUserConfigList.remove(AAAconf.getUser());
523 * A user account has been removed form local database, we assume
524 * admin does not want this user to stay connected, in case he has
525 * an open session. So we clean the active list as well.
527 removeUserFromActiveList(AAAconf.getUser());
529 localUserConfigList.put(AAAconf.getUser(), AAAconf);
532 return new Status(StatusCode.SUCCESS);
535 private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
537 if (!AAAconf.isValid()) {
538 String msg = "Invalid Server configuration";
540 return new Status(StatusCode.BADREQUEST, msg);
543 // Update configuration database
545 remoteServerConfigList.remove(AAAconf.getAddress());
547 remoteServerConfigList.put(AAAconf.getAddress(), AAAconf);
550 return new Status(StatusCode.SUCCESS);
553 private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
554 Status configCheck = AAAconf.validate();
555 if (!configCheck.isSuccess()) {
556 String msg = "Invalid Authorization configuration: "
557 + configCheck.getDescription();
559 return new Status(StatusCode.BADREQUEST, msg);
562 // Update configuration database
564 authorizationConfList.remove(AAAconf.getUser());
566 authorizationConfList.put(AAAconf.getUser(), AAAconf);
569 return new Status(StatusCode.SUCCESS);
573 public Status addLocalUser(UserConfig AAAconf) {
574 return addRemoveLocalUser(AAAconf, false);
578 public Status removeLocalUser(UserConfig AAAconf) {
579 return addRemoveLocalUser(AAAconf, true);
583 public Status removeLocalUser(String userName) {
584 if (userName == null || userName.trim().isEmpty()) {
585 return new Status(StatusCode.BADREQUEST, "Invalid user name");
588 if (!localUserConfigList.containsKey(userName)) {
589 return new Status(StatusCode.NOTFOUND, "User does not exist");
592 return addRemoveLocalUser(localUserConfigList.get(userName), true);
596 public Status addAAAServer(ServerConfig AAAconf) {
597 return addRemoveAAAServer(AAAconf, false);
601 public Status removeAAAServer(ServerConfig AAAconf) {
602 return addRemoveAAAServer(AAAconf, true);
606 public Status addAuthInfo(AuthorizationConfig AAAconf) {
607 return addRemoveAuthInfo(AAAconf, false);
611 public Status removeAuthInfo(AuthorizationConfig AAAconf) {
612 return addRemoveAuthInfo(AAAconf, true);
616 public List<UserConfig> getLocalUserList() {
617 return new ArrayList<UserConfig>(localUserConfigList.values());
621 public List<ServerConfig> getAAAServerList() {
622 return new ArrayList<ServerConfig>(remoteServerConfigList.values());
626 public List<AuthorizationConfig> getAuthorizationList() {
627 return new ArrayList<AuthorizationConfig>(
628 authorizationConfList.values());
632 public Status changeLocalUserPassword(String user, String curPassword, String newPassword) {
633 UserConfig targetConfigEntry = null;
635 // update configuration entry
636 targetConfigEntry = localUserConfigList.get(user);
637 if (targetConfigEntry == null) {
638 return new Status(StatusCode.NOTFOUND, "User not found");
640 Status status = targetConfigEntry.update(curPassword, newPassword, null);
641 if (!status.isSuccess()) {
644 // Trigger cluster update
645 localUserConfigList.put(user, targetConfigEntry);
647 logger.info("Password changed for User \"{}\"", user);
653 public void userLogout(String userName) {
654 // TODO: if user was authenticated through AAA server, send
655 // Acct-Status-Type=stop message to server with logout as reason
656 removeUserFromActiveList(userName);
657 logger.info("User \"{}\" logged out", userName);
661 * This function will get called by http session mgr when session times out
664 public void userTimedOut(String userName) {
665 // TODO: if user was authenticated through AAA server, send
666 // Acct-Status-Type=stop message to server with timeout as reason
667 removeUserFromActiveList(userName);
668 logger.info("User \"{}\" timed out", userName);
672 public String getAccessDate(String user) {
673 return this.activeUsers.get(user).getAccessDate();
677 public synchronized Map<String, List<String>> getUserLoggedIn() {
678 Map<String, List<String>> loggedInList = new HashMap<String, List<String>>();
679 for (Map.Entry<String, AuthenticatedUser> user : activeUsers.entrySet()) {
680 String userNameShow = user.getKey();
681 loggedInList.put(userNameShow, user.getValue().getUserRoles());
686 public void _umAddUser(CommandInterpreter ci) {
687 String userName = ci.nextArgument();
688 String password = ci.nextArgument();
689 String role = ci.nextArgument();
691 List<String> roles = new ArrayList<String>();
692 while (role != null) {
693 if (!role.trim().isEmpty()) {
696 role = ci.nextArgument();
699 if (userName == null || userName.trim().isEmpty() || password == null || password.trim().isEmpty()
700 || roles.isEmpty()) {
701 ci.println("Invalid Arguments");
702 ci.println("umAddUser <user_name> <password> <user_role>");
705 ci.print(this.addLocalUser(new UserConfig(userName, password, roles)));
708 public void _umRemUser(CommandInterpreter ci) {
709 String userName = ci.nextArgument();
711 if (userName == null || userName.trim().isEmpty()) {
712 ci.println("Invalid Arguments");
713 ci.println("umRemUser <user_name>");
716 UserConfig target = localUserConfigList.get(userName);
717 if (target == null) {
718 ci.println("User not found");
721 ci.println(this.removeLocalUser(target));
724 public void _umGetUsers(CommandInterpreter ci) {
725 for (UserConfig conf : this.getLocalUserList()) {
726 ci.println(conf.getUser() + " " + conf.getRoles());
730 public void _addAAAServer(CommandInterpreter ci) {
731 String server = ci.nextArgument();
732 String secret = ci.nextArgument();
733 String protocol = ci.nextArgument();
735 if (server == null || secret == null || protocol == null) {
736 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
739 ServerConfig s = new ServerConfig(server, secret, protocol);
743 public void _removeAAAServer(CommandInterpreter ci) {
744 String server = ci.nextArgument();
745 String secret = ci.nextArgument();
746 String protocol = ci.nextArgument();
748 if (server == null || secret == null || protocol == null) {
749 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
752 ServerConfig s = new ServerConfig(server, secret, protocol);
756 public void _printAAAServers(CommandInterpreter ci) {
757 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
758 ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
763 public String getHelp() {
764 StringBuffer help = new StringBuffer();
765 return help.toString();
768 void setClusterGlobalService(IClusterGlobalServices s) {
769 logger.debug("Cluster Service Global set");
770 this.clusterGlobalService = s;
773 void unsetClusterGlobalService(IClusterGlobalServices s) {
774 if (this.clusterGlobalService == s) {
775 logger.debug("Cluster Service Global removed!");
776 this.clusterGlobalService = null;
780 void unsetContainerAuthClient(IContainerAuthorization s) {
781 if (this.containerAuthorizationClient == s) {
782 this.containerAuthorizationClient = null;
786 void setContainerAuthClient(IContainerAuthorization s) {
787 this.containerAuthorizationClient = s;
790 void setAppAuthClient(IResourceAuthorization s) {
791 this.applicationAuthorizationClients.add(s);
794 void unsetAppAuthClient(IResourceAuthorization s) {
795 this.applicationAuthorizationClients.remove(s);
799 * Function called by the dependency manager when all the required
800 * dependencies are satisfied
807 * Function called by the dependency manager when at least one dependency
808 * become unsatisfied or when the component is shutting down because for
809 * example bundle is being stopped.
816 * Function called by dependency manager after "init ()" is called and after
817 * the services provided by the class are registered in the service registry
821 authProviders = new ConcurrentHashMap<String, IAAAProvider>();
822 // Instantiate cluster synced variables
826 // Read startup configuration and populate databases
827 loadConfigurations();
829 // Check if a password recovery was triggered for default network admin user
830 checkPasswordRecovery();
832 // Make sure default Network Admin account is there
833 checkDefaultNetworkAdmin();
835 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
836 bundleContext.registerService(CommandProvider.class.getName(), this, null);
840 * Function called by the dependency manager before the services exported by
841 * the component are unregistered, this will be followed by a "destroy ()"
849 public List<String> getUserRoles(String userName) {
850 List<String> roles = null;
851 if (userName != null) {
853 * First look in active users then in local configured users,
854 * finally in local authorized users
856 if (activeUsers.containsKey(userName)) {
857 roles = activeUsers.get(userName).getUserRoles();
858 } else if (localUserConfigList.containsKey(userName)) {
859 roles = localUserConfigList.get(userName).getRoles();
860 } else if (authorizationConfList.containsKey(userName)) {
861 roles = authorizationConfList.get(userName).getRoles();
864 return (roles == null) ? new ArrayList<String>(0) : roles;
868 public UserLevel getUserLevel(String username) {
869 // Returns the highest controller user level for the passed user
870 List<String> rolesNames = getUserRoles(username);
872 if (rolesNames.isEmpty()) {
873 return UserLevel.NOUSER;
876 // Check against the well known controller roles first
877 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
878 return UserLevel.SYSTEMADMIN;
880 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
881 return UserLevel.NETWORKADMIN;
883 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
884 return UserLevel.NETWORKOPERATOR;
886 // Check if container user now
887 if (containerAuthorizationClient != null) {
888 for (String roleName : rolesNames) {
889 if (containerAuthorizationClient.isApplicationRole(roleName)) {
890 return UserLevel.CONTAINERUSER;
894 // Finally check if application user
895 if (applicationAuthorizationClients != null) {
896 for (String roleName : rolesNames) {
897 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
898 if (client.isApplicationRole(roleName)) {
899 return UserLevel.APPUSER;
904 return UserLevel.NOUSER;
909 public List<UserLevel> getUserLevels(String username) {
910 // Returns the controller user levels for the passed user
911 List<String> rolesNames = getUserRoles(username);
912 List<UserLevel> levels = new ArrayList<UserLevel>();
914 if (rolesNames.isEmpty()) {
918 // Check against the well known controller roles first
919 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
920 levels.add(UserLevel.SYSTEMADMIN);
922 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
923 levels.add(UserLevel.NETWORKADMIN);
925 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
926 levels.add(UserLevel.NETWORKOPERATOR);
928 // Check if container user now
929 if (containerAuthorizationClient != null) {
930 for (String roleName : rolesNames) {
931 if (containerAuthorizationClient.isApplicationRole(roleName)) {
932 levels.add(UserLevel.CONTAINERUSER);
937 // Finally check if application user
938 if (applicationAuthorizationClients != null) {
939 for (String roleName : rolesNames) {
940 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
941 if (client.isApplicationRole(roleName)) {
942 levels.add(UserLevel.APPUSER);
952 public Status saveConfiguration() {
953 boolean success = true;
954 Status ret = saveLocalUserList();
955 if (!ret.isSuccess()) {
958 ret = saveAAAServerList();
959 if (!ret.isSuccess()) {
962 ret = saveAuthorizationList();
963 if (!ret.isSuccess()) {
968 return new Status(StatusCode.SUCCESS);
971 return new Status(StatusCode.INTERNALERROR, "Failed to save user configurations");
975 public UserDetails loadUserByUsername(String username)
976 throws UsernameNotFoundException {
977 AuthenticatedUser user = activeUsers.get(username);
980 boolean enabled = true;
981 boolean accountNonExpired = true;
982 boolean credentialsNonExpired = true;
983 boolean accountNonLocked = true;
985 return new User(username, localUserConfigList.get(username)
986 .getPassword(), enabled, accountNonExpired,
987 credentialsNonExpired, accountNonLocked,
988 user.getGrantedAuthorities(getUserLevel(username)));
990 throw new UsernameNotFoundException("User not found " + username);
995 public boolean supports(Class<?> authentication) {
996 return UsernamePasswordAuthenticationToken.class
997 .isAssignableFrom(authentication);
1002 public SecurityContextRepository getSecurityContextRepo() {
1003 return securityContextRepo;
1006 public void setSecurityContextRepo(
1007 SecurityContextRepository securityContextRepo) {
1008 this.securityContextRepo = securityContextRepo;
1012 public Authentication authenticate(Authentication authentication)
1013 throws AuthenticationException {
1015 if (StringUtils.isBlank((String) authentication.getCredentials())
1016 || StringUtils.isBlank((String) authentication.getPrincipal())) {
1017 throw new BadCredentialsException(
1018 "Username or credentials did not match");
1021 AuthResultEnum result = authenticate(
1022 (String) authentication.getPrincipal(),
1023 (String) authentication.getCredentials());
1024 if (result.equals(AuthResultEnum.AUTHOR_PASS)
1025 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
1026 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
1028 AuthenticatedUser user = activeUsers.get(authentication
1029 .getPrincipal().toString());
1032 throw new AuthenticationServiceException(
1033 "Authentication Failure");
1036 authentication = new UsernamePasswordAuthenticationToken(
1037 authentication.getPrincipal(),
1038 authentication.getCredentials(),
1039 user.getGrantedAuthorities(getUserLevel(authentication
1041 return authentication;
1044 throw new BadCredentialsException(
1045 "Username or credentials did not match");
1050 // Following are setters for use in unit testing
1051 void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1053 this.localUserConfigList = ucl;
1057 void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1059 this.remoteServerConfigList = scl;
1063 void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1065 this.authorizationConfList = acl;
1069 void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1071 this.activeUsers = au;
1075 void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1077 this.authProviders = ap;
1082 public ISessionManager getSessionManager() {
1083 return this.sessionMgr;
1086 public void setSessionMgr(ISessionManager sessionMgr) {
1087 this.sessionMgr = sessionMgr;
1091 public String getPassword(String username) {
1092 return localUserConfigList.get(username).getPassword();
1096 public boolean isRoleInUse(String role) {
1097 if (role == null || role.isEmpty()) {
1100 // Check against controller roles
1101 if (role.equals(UserLevel.SYSTEMADMIN.toString())
1102 || role.equals(UserLevel.NETWORKADMIN.toString())
1103 || role.equals(UserLevel.NETWORKOPERATOR.toString())) {
1106 // Check if container roles
1107 if (containerAuthorizationClient != null) {
1108 if (containerAuthorizationClient.isApplicationRole(role)) {
1112 // Finally if application role
1113 if (applicationAuthorizationClients != null) {
1114 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
1115 if (client.isApplicationRole(role)) {