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.GlobalConstants;
40 import org.opendaylight.controller.sal.utils.IObjectReader;
41 import org.opendaylight.controller.sal.utils.ObjectReader;
42 import org.opendaylight.controller.sal.utils.ObjectWriter;
43 import org.opendaylight.controller.sal.utils.Status;
44 import org.opendaylight.controller.sal.utils.StatusCode;
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;
55 import org.osgi.framework.BundleContext;
56 import org.osgi.framework.FrameworkUtil;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59 import org.springframework.security.authentication.AuthenticationProvider;
60 import org.springframework.security.authentication.AuthenticationServiceException;
61 import org.springframework.security.authentication.BadCredentialsException;
62 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
63 import org.springframework.security.core.Authentication;
64 import org.springframework.security.core.AuthenticationException;
65 import org.springframework.security.core.userdetails.User;
66 import org.springframework.security.core.userdetails.UserDetails;
67 import org.springframework.security.core.userdetails.UsernameNotFoundException;
68 import org.springframework.security.web.context.SecurityContextRepository;
71 * The internal implementation of the User Manager.
73 public class UserManager implements IUserManager, IObjectReader,
74 IConfigurationAware, CommandProvider, AuthenticationProvider {
75 private static final Logger logger = LoggerFactory.getLogger(UserManager.class);
76 private static final String DEFAULT_ADMIN = "admin";
77 private static final String DEFAULT_ADMIN_PASSWORD = "admin";
78 private static final String DEFAULT_ADMIN_ROLE = UserLevel.NETWORKADMIN.toString();
79 private static final String ROOT = GlobalConstants.STARTUPHOME.toString();
80 private static final String USERS_FILE_NAME = ROOT + "users.conf";
81 private static final String SERVERS_FILE_NAME = ROOT + "servers.conf";
82 private static final String AUTH_FILE_NAME = ROOT + "authorization.conf";
83 private static final String RECOVERY_FILE = ROOT + "NETWORK_ADMIN_PASSWORD_RECOVERY";
84 private ConcurrentMap<String, UserConfig> localUserConfigList;
85 private ConcurrentMap<String, ServerConfig> remoteServerConfigList;
86 // local authorization info for remotely authenticated users
87 private ConcurrentMap<String, AuthorizationConfig> authorizationConfList;
88 private ConcurrentMap<String, AuthenticatedUser> activeUsers;
89 private ConcurrentMap<String, IAAAProvider> authProviders;
90 private IClusterGlobalServices clusterGlobalService = null;
91 private SecurityContextRepository securityContextRepo = new UserSecurityContextRepository();
92 private IContainerAuthorization containerAuthorizationClient;
93 private Set<IResourceAuthorization> applicationAuthorizationClients;
94 private ISessionManager sessionMgr = new SessionManager();
95 protected enum Command {
97 MODIFY("modify", "modified"),
98 REMOVE("remove", "removed");
99 private String action;
100 private String postAction;
101 private Command(String action, String postAction) {
102 this.action = action;
103 this.postAction = postAction;
106 public String getAction() {
110 public String getPostAction() {
115 public boolean addAAAProvider(IAAAProvider provider) {
116 if (provider == null || provider.getName() == null
117 || provider.getName().trim().isEmpty()) {
120 if (authProviders.get(provider.getName()) != null) {
124 authProviders.put(provider.getName(), provider);
128 public void removeAAAProvider(IAAAProvider provider) {
129 authProviders.remove(provider.getName());
132 public IAAAProvider getAAAProvider(String name) {
133 return authProviders.get(name);
137 public Set<String> getAAAProviderNames() {
138 return authProviders.keySet();
141 private void allocateCaches() {
142 this.applicationAuthorizationClients = Collections.synchronizedSet(new HashSet<IResourceAuthorization>());
143 if (clusterGlobalService == null) {
144 logger.error("un-initialized clusterGlobalService, can't create cache");
149 clusterGlobalService.createCache("usermanager.localUserConfigList",
150 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
152 clusterGlobalService.createCache(
153 "usermanager.remoteServerConfigList",
154 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
156 clusterGlobalService.createCache(
157 "usermanager.authorizationConfList",
158 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
160 clusterGlobalService.createCache("usermanager.activeUsers",
161 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
162 } catch (CacheConfigException cce) {
163 logger.error("Cache configuration invalid - check cache mode");
164 } catch (CacheExistException ce) {
165 logger.debug("Skipping cache creation as already present");
169 @SuppressWarnings({ "unchecked" })
170 private void retrieveCaches() {
171 if (clusterGlobalService == null) {
172 logger.error("un-initialized clusterService, can't retrieve cache");
176 activeUsers = (ConcurrentMap<String, AuthenticatedUser>) clusterGlobalService
177 .getCache("usermanager.activeUsers");
178 if (activeUsers == null) {
179 logger.error("Failed to get cache for activeUsers");
182 localUserConfigList = (ConcurrentMap<String, UserConfig>) clusterGlobalService
183 .getCache("usermanager.localUserConfigList");
184 if (localUserConfigList == null) {
185 logger.error("Failed to get cache for localUserConfigList");
188 remoteServerConfigList = (ConcurrentMap<String, ServerConfig>) clusterGlobalService
189 .getCache("usermanager.remoteServerConfigList");
190 if (remoteServerConfigList == null) {
191 logger.error("Failed to get cache for remoteServerConfigList");
194 authorizationConfList = (ConcurrentMap<String, AuthorizationConfig>) clusterGlobalService
195 .getCache("usermanager.authorizationConfList");
196 if (authorizationConfList == null) {
197 logger.error("Failed to get cache for authorizationConfList");
201 private void loadConfigurations() {
202 // To encode and decode user and server configuration objects
205 * Do not load local startup file if we are not the coordinator
207 if ((clusterGlobalService != null) && (clusterGlobalService.amICoordinator())) {
214 private void loadSecurityKeys() {
218 private void checkDefaultNetworkAdmin() {
220 * If startup config is not there, it's old or it was deleted or if a
221 * password recovery was run, need to add Default Network Admin User
223 if (!localUserConfigList.containsKey(DEFAULT_ADMIN)) {
224 List<String> roles = new ArrayList<String>(1);
225 roles.add(DEFAULT_ADMIN_ROLE);
226 // Need to skip the strong password check for the default admin
227 UserConfig defaultAdmin = UserConfig.getUncheckedUserConfig(UserManager.DEFAULT_ADMIN,
228 UserManager.DEFAULT_ADMIN_PASSWORD, roles);
229 localUserConfigList.put(UserManager.DEFAULT_ADMIN, defaultAdmin);
233 private void checkPasswordRecovery() {
234 final String fileDescription = "Default Network Administrator password recovery file";
236 FileInputStream fis = new FileInputStream(UserManager.RECOVERY_FILE);
238 * Recovery file detected, remove current default network
239 * administrator entry from local users configuration list.
240 * Warn user and delete recovery file.
242 this.localUserConfigList.remove(UserManager.DEFAULT_ADMIN);
243 logger.info("Default Network Administrator password has been reset to factory default.");
244 logger.info("Please change the default Network Administrator password as soon as possible");
245 File filePointer = new File(UserManager.RECOVERY_FILE);
246 boolean status = filePointer.delete();
248 logger.warn("Failed to delete {}", fileDescription);
250 logger.trace("{} deleted", fileDescription);
253 } catch (FileNotFoundException fnf) {
254 logger.trace("{} not present", fileDescription);
255 } catch (IOException e) {
256 logger.warn("Failed to close file stream for {}", fileDescription);
261 public AuthResultEnum authenticate(String userName, String password) {
262 IAAAProvider aaaClient;
263 AuthResponse rcResponse = null;
264 AuthenticatedUser result;
265 boolean remotelyAuthenticated = false;
266 boolean authorizationInfoIsPresent = false;
267 boolean authorized = false;
270 * Attempt remote authentication first if server is configured
272 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
273 String protocol = aaaServer.getProtocol();
274 aaaClient = this.getAAAProvider(protocol);
275 if (aaaClient != null) {
276 rcResponse = aaaClient.authService(userName, password,
277 aaaServer.getAddress(), aaaServer.getSecret());
278 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
280 "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
281 userName, aaaServer.getAddress());
282 remotelyAuthenticated = true;
284 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
286 "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
287 new Object[] { userName, aaaServer.getAddress(),
288 rcResponse.getStatus().toString() });
291 "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
292 new Object[] { userName, aaaServer.getAddress(),
293 rcResponse.getStatus().toString() });
298 if (!remotelyAuthenticated) {
299 UserConfig localUser = this.localUserConfigList.get(userName);
300 if (localUser == null) {
302 "Local Authentication Failed for User:\"{}\", Reason: "
303 + "user not found in Local Database", userName);
304 return (AuthResultEnum.AUTH_INVALID_LOC_USER);
306 rcResponse = localUser.authenticate(password);
307 if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
309 "Local Authentication Failed for User: \"{}\", Reason: {}",
310 userName, rcResponse.getStatus().toString());
312 return (rcResponse.getStatus());
314 logger.info("Local Authentication Succeeded for User: \"{}\"",
319 * Authentication succeeded
321 result = new AuthenticatedUser(userName);
324 * Extract attributes from response All the information we are
325 * interested in is in the first Cisco VSA (vendor specific attribute).
326 * Just process the first VSA and return
328 String attributes = (rcResponse.getData() != null && !rcResponse
329 .getData().isEmpty()) ? rcResponse.getData().get(0) : null;
332 * Check if the authorization information is present
334 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
337 * The AAA server was only used to perform the authentication Look for
338 * locally stored authorization info for this user If found, add the
339 * data to the rcResponse
341 if (remotelyAuthenticated && !authorizationInfoIsPresent) {
343 "No Remote Authorization Info provided by Server for User: \"{}\"",
346 "Looking for Local Authorization Info for User: \"{}\"",
349 AuthorizationConfig resource = authorizationConfList.get(userName);
350 if (resource != null) {
351 logger.info("Found Local Authorization Info for User: \"{}\"",
353 attributes = resource.getRolesString();
356 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
360 * Common response parsing for local & remote authenticated user Looking
361 * for authorized resources, detecting attributes' validity
363 if (authorizationInfoIsPresent) {
364 // Identifying the administrative role
365 result.setRoleList(attributes.split(" "));
368 logger.info("Not able to find Authorization Info for User: \"{}\"",
373 * Add profile for authenticated user
375 putUserInActiveList(userName, result);
377 logger.info("User \"{}\" authorized for the following role(s): {}",
378 userName, result.getUserRoles());
380 logger.info("User \"{}\" Not Authorized for any role ", userName);
383 return rcResponse.getStatus();
386 // Check in the attributes string whether or not authorization information
388 private boolean checkAuthorizationInfo(String attributes) {
389 return (attributes != null && !attributes.isEmpty());
392 private void putUserInActiveList(String user, AuthenticatedUser result) {
393 activeUsers.put(user, result);
396 private void removeUserFromActiveList(String user) {
397 if (!activeUsers.containsKey(user)) {
398 // as cookie persists in cache, we can get logout for unexisting
402 activeUsers.remove(user);
406 public Status saveLocalUserList() {
407 return saveLocalUserListInternal();
410 private Status saveLocalUserListInternal() {
411 ObjectWriter objWriter = new ObjectWriter();
412 return objWriter.write(new ConcurrentHashMap<String, UserConfig>(
413 localUserConfigList), USERS_FILE_NAME);
417 public Status saveAAAServerList() {
418 return saveAAAServerListInternal();
421 private Status saveAAAServerListInternal() {
422 ObjectWriter objWriter = new ObjectWriter();
423 return objWriter.write(new ConcurrentHashMap<String, ServerConfig>(
424 remoteServerConfigList), SERVERS_FILE_NAME);
428 public Status saveAuthorizationList() {
429 return saveAuthorizationListInternal();
432 private Status saveAuthorizationListInternal() {
433 ObjectWriter objWriter = new ObjectWriter();
434 return objWriter.write(
435 new ConcurrentHashMap<String, AuthorizationConfig>(
436 authorizationConfList), AUTH_FILE_NAME);
440 public Object readObject(ObjectInputStream ois)
441 throws FileNotFoundException, IOException, ClassNotFoundException {
442 // Perform the class deserialization locally, from inside the package
443 // where the class is defined
444 return ois.readObject();
447 @SuppressWarnings("unchecked")
448 private void loadUserConfig() {
449 ObjectReader objReader = new ObjectReader();
450 ConcurrentMap<String, UserConfig> confList = (ConcurrentMap<String, UserConfig>) objReader
451 .read(this, USERS_FILE_NAME);
453 if (confList == null) {
457 for (UserConfig conf : confList.values()) {
458 addRemoveLocalUserInternal(conf, false);
462 @SuppressWarnings("unchecked")
463 private void loadServerConfig() {
464 ObjectReader objReader = new ObjectReader();
465 ConcurrentMap<String, ServerConfig> confList = (ConcurrentMap<String, ServerConfig>) objReader
466 .read(this, SERVERS_FILE_NAME);
468 if (confList == null) {
472 for (ServerConfig conf : confList.values()) {
477 @SuppressWarnings("unchecked")
478 private void loadAuthConfig() {
479 ObjectReader objReader = new ObjectReader();
480 ConcurrentMap<String, AuthorizationConfig> confList = (ConcurrentMap<String, AuthorizationConfig>) objReader
481 .read(this, AUTH_FILE_NAME);
483 if (confList == null) {
487 for (AuthorizationConfig conf : confList.values()) {
493 * Interaction with GUI START
495 private Status changeLocalUser(UserConfig AAAconf, Command command) {
496 // UserConfig Validation check
497 Status validCheck = AAAconf.validate();
498 if (!validCheck.isSuccess()) {
502 String user = AAAconf.getUser();
504 // Check default admin user
505 if (user.equals(UserManager.DEFAULT_ADMIN)) {
506 String msg = String.format("Invalid Request: Default Network Admin User cannot be %s", command.getPostAction());
508 return new Status(StatusCode.NOTALLOWED, msg);
511 // Check user presence/conflict
512 UserConfig currentAAAconf = localUserConfigList.get(user);
513 StatusCode statusCode = null;
514 String reason = null;
517 if (currentAAAconf != null) {
518 reason = "already present";
519 statusCode = StatusCode.CONFLICT;
524 if (currentAAAconf == null) {
525 reason = "not found";
526 statusCode = StatusCode.NOTFOUND;
533 if (statusCode != null) {
534 String action = String.format("Failed to %s user %s: ", command.getAction(), user);
535 String msg = String.format("User %s %s in configuration database", user, reason);
536 logger.debug(action + msg);
537 return new Status(statusCode, msg);
542 return addRemoveLocalUserInternal(AAAconf, false);
544 addRemoveLocalUserInternal(currentAAAconf, true);
545 return addRemoveLocalUserInternal(AAAconf, false);
547 return addRemoveLocalUserInternal(AAAconf, true);
549 return new Status(StatusCode.INTERNALERROR, "Unknown action");
553 private Status addRemoveLocalUserInternal(UserConfig AAAconf, boolean delete) {
554 // Update Config database
556 localUserConfigList.remove(AAAconf.getUser());
558 * A user account has been removed form local database, we assume
559 * admin does not want this user to stay connected, in case he has
560 * an open session. So we clean the active list as well.
562 removeUserFromActiveList(AAAconf.getUser());
564 localUserConfigList.put(AAAconf.getUser(), AAAconf);
567 return new Status(StatusCode.SUCCESS);
570 private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
572 if (!AAAconf.isValid()) {
573 String msg = "Invalid Server configuration";
575 return new Status(StatusCode.BADREQUEST, msg);
578 // Update configuration database
580 remoteServerConfigList.remove(AAAconf.getAddress());
582 remoteServerConfigList.put(AAAconf.getAddress(), AAAconf);
585 return new Status(StatusCode.SUCCESS);
588 private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
589 Status configCheck = AAAconf.validate();
590 if (!configCheck.isSuccess()) {
591 String msg = "Invalid Authorization configuration: "
592 + configCheck.getDescription();
594 return new Status(StatusCode.BADREQUEST, msg);
597 // Update configuration database
599 authorizationConfList.remove(AAAconf.getUser());
601 authorizationConfList.put(AAAconf.getUser(), AAAconf);
604 return new Status(StatusCode.SUCCESS);
608 public Status addLocalUser(UserConfig AAAconf) {
609 return changeLocalUser(AAAconf, Command.ADD);
613 public Status modifyLocalUser(UserConfig AAAconf) {
614 return changeLocalUser(AAAconf, Command.MODIFY);
618 public Status removeLocalUser(UserConfig AAAconf) {
619 return changeLocalUser(AAAconf, Command.REMOVE);
623 public Status removeLocalUser(String userName) {
624 if (userName == null || userName.trim().isEmpty()) {
625 return new Status(StatusCode.BADREQUEST, "Invalid user name");
628 if (!localUserConfigList.containsKey(userName)) {
629 return new Status(StatusCode.NOTFOUND, "User does not exist");
632 return changeLocalUser(localUserConfigList.get(userName), Command.REMOVE);
636 public Status addAAAServer(ServerConfig AAAconf) {
637 return addRemoveAAAServer(AAAconf, false);
641 public Status removeAAAServer(ServerConfig AAAconf) {
642 return addRemoveAAAServer(AAAconf, true);
646 public Status addAuthInfo(AuthorizationConfig AAAconf) {
647 return addRemoveAuthInfo(AAAconf, false);
651 public Status removeAuthInfo(AuthorizationConfig AAAconf) {
652 return addRemoveAuthInfo(AAAconf, true);
656 public List<UserConfig> getLocalUserList() {
657 return new ArrayList<UserConfig>(localUserConfigList.values());
661 public List<ServerConfig> getAAAServerList() {
662 return new ArrayList<ServerConfig>(remoteServerConfigList.values());
666 public List<AuthorizationConfig> getAuthorizationList() {
667 return new ArrayList<AuthorizationConfig>(
668 authorizationConfList.values());
672 public Status changeLocalUserPassword(String user, String curPassword, String newPassword) {
673 UserConfig targetConfigEntry = null;
675 // update configuration entry
676 targetConfigEntry = localUserConfigList.get(user);
677 if (targetConfigEntry == null) {
678 return new Status(StatusCode.NOTFOUND, "User not found");
680 Status status = targetConfigEntry.update(curPassword, newPassword, null);
681 if (!status.isSuccess()) {
684 // Trigger cluster update
685 localUserConfigList.put(user, targetConfigEntry);
687 logger.info("Password changed for User \"{}\"", user);
693 public void userLogout(String userName) {
694 // TODO: if user was authenticated through AAA server, send
695 // Acct-Status-Type=stop message to server with logout as reason
696 removeUserFromActiveList(userName);
697 logger.info("User \"{}\" logged out", userName);
701 * This function will get called by http session mgr when session times out
704 public void userTimedOut(String userName) {
705 // TODO: if user was authenticated through AAA server, send
706 // Acct-Status-Type=stop message to server with timeout as reason
707 removeUserFromActiveList(userName);
708 logger.info("User \"{}\" timed out", userName);
712 public String getAccessDate(String user) {
713 return this.activeUsers.get(user).getAccessDate();
717 public synchronized Map<String, List<String>> getUserLoggedIn() {
718 Map<String, List<String>> loggedInList = new HashMap<String, List<String>>();
719 for (Map.Entry<String, AuthenticatedUser> user : activeUsers.entrySet()) {
720 String userNameShow = user.getKey();
721 loggedInList.put(userNameShow, user.getValue().getUserRoles());
726 public void _umAddUser(CommandInterpreter ci) {
727 String userName = ci.nextArgument();
728 String password = ci.nextArgument();
729 String role = ci.nextArgument();
731 List<String> roles = new ArrayList<String>();
732 while (role != null) {
733 if (!role.trim().isEmpty()) {
736 role = ci.nextArgument();
739 if (userName == null || userName.trim().isEmpty() || password == null || password.trim().isEmpty()
740 || roles.isEmpty()) {
741 ci.println("Invalid Arguments");
742 ci.println("umAddUser <user_name> <password> <user_role>");
745 ci.print(this.addLocalUser(new UserConfig(userName, password, roles)));
748 public void _umRemUser(CommandInterpreter ci) {
749 String userName = ci.nextArgument();
751 if (userName == null || userName.trim().isEmpty()) {
752 ci.println("Invalid Arguments");
753 ci.println("umRemUser <user_name>");
756 UserConfig target = localUserConfigList.get(userName);
757 if (target == null) {
758 ci.println("User not found");
761 ci.println(this.removeLocalUser(target));
764 public void _umGetUsers(CommandInterpreter ci) {
765 for (UserConfig conf : this.getLocalUserList()) {
766 ci.println(conf.getUser() + " " + conf.getRoles());
770 public void _addAAAServer(CommandInterpreter ci) {
771 String server = ci.nextArgument();
772 String secret = ci.nextArgument();
773 String protocol = ci.nextArgument();
775 if (server == null || secret == null || protocol == null) {
776 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
779 ServerConfig s = new ServerConfig(server, secret, protocol);
783 public void _removeAAAServer(CommandInterpreter ci) {
784 String server = ci.nextArgument();
785 String secret = ci.nextArgument();
786 String protocol = ci.nextArgument();
788 if (server == null || secret == null || protocol == null) {
789 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
792 ServerConfig s = new ServerConfig(server, secret, protocol);
796 public void _printAAAServers(CommandInterpreter ci) {
797 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
798 ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
803 public String getHelp() {
804 StringBuffer help = new StringBuffer();
805 return help.toString();
808 void setClusterGlobalService(IClusterGlobalServices s) {
809 logger.debug("Cluster Service Global set");
810 this.clusterGlobalService = s;
813 void unsetClusterGlobalService(IClusterGlobalServices s) {
814 if (this.clusterGlobalService == s) {
815 logger.debug("Cluster Service Global removed!");
816 this.clusterGlobalService = null;
820 void unsetContainerAuthClient(IContainerAuthorization s) {
821 if (this.containerAuthorizationClient == s) {
822 this.containerAuthorizationClient = null;
826 void setContainerAuthClient(IContainerAuthorization s) {
827 this.containerAuthorizationClient = s;
830 void setAppAuthClient(IResourceAuthorization s) {
831 this.applicationAuthorizationClients.add(s);
834 void unsetAppAuthClient(IResourceAuthorization s) {
835 this.applicationAuthorizationClients.remove(s);
839 * Function called by the dependency manager when all the required
840 * dependencies are satisfied
847 * Function called by the dependency manager when at least one dependency
848 * become unsatisfied or when the component is shutting down because for
849 * example bundle is being stopped.
856 * Function called by dependency manager after "init ()" is called and after
857 * the services provided by the class are registered in the service registry
861 authProviders = new ConcurrentHashMap<String, IAAAProvider>();
862 // Instantiate cluster synced variables
866 // Read startup configuration and populate databases
867 loadConfigurations();
869 // Check if a password recovery was triggered for default network admin user
870 checkPasswordRecovery();
872 // Make sure default Network Admin account is there
873 checkDefaultNetworkAdmin();
875 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
876 bundleContext.registerService(CommandProvider.class.getName(), this, null);
880 * Function called by the dependency manager before the services exported by
881 * the component are unregistered, this will be followed by a "destroy ()"
889 public List<String> getUserRoles(String userName) {
890 List<String> roles = null;
891 if (userName != null) {
893 * First look in active users then in local configured users,
894 * finally in local authorized users
896 if (activeUsers.containsKey(userName)) {
897 roles = activeUsers.get(userName).getUserRoles();
898 } else if (localUserConfigList.containsKey(userName)) {
899 roles = localUserConfigList.get(userName).getRoles();
900 } else if (authorizationConfList.containsKey(userName)) {
901 roles = authorizationConfList.get(userName).getRoles();
904 return (roles == null) ? new ArrayList<String>(0) : roles;
908 public UserLevel getUserLevel(String username) {
909 // Returns the highest controller user level for the passed user
910 List<String> rolesNames = getUserRoles(username);
912 if (rolesNames.isEmpty()) {
913 return UserLevel.NOUSER;
916 // Check against the well known controller roles first
917 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
918 return UserLevel.SYSTEMADMIN;
920 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
921 return UserLevel.NETWORKADMIN;
923 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
924 return UserLevel.NETWORKOPERATOR;
926 // Check if container user now
927 if (containerAuthorizationClient != null) {
928 for (String roleName : rolesNames) {
929 if (containerAuthorizationClient.isApplicationRole(roleName)) {
930 return UserLevel.CONTAINERUSER;
934 // Finally check if application user
935 if (applicationAuthorizationClients != null) {
936 for (String roleName : rolesNames) {
937 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
938 if (client.isApplicationRole(roleName)) {
939 return UserLevel.APPUSER;
944 return UserLevel.NOUSER;
949 public List<UserLevel> getUserLevels(String username) {
950 // Returns the controller user levels for the passed user
951 List<String> rolesNames = getUserRoles(username);
952 List<UserLevel> levels = new ArrayList<UserLevel>();
954 if (rolesNames.isEmpty()) {
958 // Check against the well known controller roles first
959 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
960 levels.add(UserLevel.SYSTEMADMIN);
962 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
963 levels.add(UserLevel.NETWORKADMIN);
965 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
966 levels.add(UserLevel.NETWORKOPERATOR);
968 // Check if container user now
969 if (containerAuthorizationClient != null) {
970 for (String roleName : rolesNames) {
971 if (containerAuthorizationClient.isApplicationRole(roleName)) {
972 levels.add(UserLevel.CONTAINERUSER);
977 // Finally check if application user
978 if (applicationAuthorizationClients != null) {
979 for (String roleName : rolesNames) {
980 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
981 if (client.isApplicationRole(roleName)) {
982 levels.add(UserLevel.APPUSER);
992 public Status saveConfiguration() {
993 boolean success = true;
994 Status ret = saveLocalUserList();
995 if (!ret.isSuccess()) {
998 ret = saveAAAServerList();
999 if (!ret.isSuccess()) {
1002 ret = saveAuthorizationList();
1003 if (!ret.isSuccess()) {
1008 return new Status(StatusCode.SUCCESS);
1011 return new Status(StatusCode.INTERNALERROR, "Failed to save user configurations");
1015 public UserDetails loadUserByUsername(String username)
1016 throws UsernameNotFoundException {
1017 AuthenticatedUser user = activeUsers.get(username);
1020 boolean enabled = true;
1021 boolean accountNonExpired = true;
1022 boolean credentialsNonExpired = true;
1023 boolean accountNonLocked = true;
1025 return new User(username, localUserConfigList.get(username)
1026 .getPassword(), enabled, accountNonExpired,
1027 credentialsNonExpired, accountNonLocked,
1028 user.getGrantedAuthorities(getUserLevel(username)));
1030 throw new UsernameNotFoundException("User not found " + username);
1035 public boolean supports(Class<?> authentication) {
1036 return UsernamePasswordAuthenticationToken.class
1037 .isAssignableFrom(authentication);
1042 public SecurityContextRepository getSecurityContextRepo() {
1043 return securityContextRepo;
1046 public void setSecurityContextRepo(
1047 SecurityContextRepository securityContextRepo) {
1048 this.securityContextRepo = securityContextRepo;
1052 public Authentication authenticate(Authentication authentication)
1053 throws AuthenticationException {
1055 if (StringUtils.isBlank((String) authentication.getCredentials())
1056 || StringUtils.isBlank((String) authentication.getPrincipal())) {
1057 throw new BadCredentialsException(
1058 "Username or credentials did not match");
1061 AuthResultEnum result = authenticate(
1062 (String) authentication.getPrincipal(),
1063 (String) authentication.getCredentials());
1064 if (result.equals(AuthResultEnum.AUTHOR_PASS)
1065 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
1066 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
1068 AuthenticatedUser user = activeUsers.get(authentication
1069 .getPrincipal().toString());
1072 throw new AuthenticationServiceException(
1073 "Authentication Failure");
1076 authentication = new UsernamePasswordAuthenticationToken(
1077 authentication.getPrincipal(),
1078 authentication.getCredentials(),
1079 user.getGrantedAuthorities(getUserLevel(authentication
1081 return authentication;
1084 throw new BadCredentialsException(
1085 "Username or credentials did not match");
1090 // Following are setters for use in unit testing
1091 void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1093 this.localUserConfigList = ucl;
1097 void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1099 this.remoteServerConfigList = scl;
1103 void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1105 this.authorizationConfList = acl;
1109 void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1111 this.activeUsers = au;
1115 void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1117 this.authProviders = ap;
1122 public ISessionManager getSessionManager() {
1123 return this.sessionMgr;
1126 public void setSessionMgr(ISessionManager sessionMgr) {
1127 this.sessionMgr = sessionMgr;
1131 public String getPassword(String username) {
1132 return localUserConfigList.get(username).getPassword();
1136 public boolean isRoleInUse(String role) {
1137 if (role == null || role.isEmpty()) {
1140 // Check against controller roles
1141 if (role.equals(UserLevel.SYSTEMADMIN.toString())
1142 || role.equals(UserLevel.NETWORKADMIN.toString())
1143 || role.equals(UserLevel.NETWORKOPERATOR.toString())) {
1146 // Check if container roles
1147 if (containerAuthorizationClient != null) {
1148 if (containerAuthorizationClient.isApplicationRole(role)) {
1152 // Finally if application role
1153 if (applicationAuthorizationClients != null) {
1154 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
1155 if (client.isApplicationRole(role)) {