2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.usermanager.internal;
11 import java.io.FileNotFoundException;
12 import java.io.IOException;
13 import java.io.ObjectInputStream;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.EnumSet;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.List;
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.ConcurrentMap;
25 import org.apache.commons.lang3.StringUtils;
26 import org.eclipse.osgi.framework.console.CommandInterpreter;
27 import org.eclipse.osgi.framework.console.CommandProvider;
28 import org.opendaylight.controller.clustering.services.CacheConfigException;
29 import org.opendaylight.controller.clustering.services.CacheExistException;
30 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
31 import org.opendaylight.controller.clustering.services.IClusterServices;
32 import org.opendaylight.controller.configuration.IConfigurationAware;
33 import org.opendaylight.controller.containermanager.IContainerAuthorization;
34 import org.opendaylight.controller.sal.authorization.AuthResultEnum;
35 import org.opendaylight.controller.sal.authorization.IResourceAuthorization;
36 import org.opendaylight.controller.sal.authorization.UserLevel;
37 import org.opendaylight.controller.sal.utils.StatusCode;
38 import org.opendaylight.controller.sal.utils.GlobalConstants;
39 import org.opendaylight.controller.sal.utils.IObjectReader;
40 import org.opendaylight.controller.sal.utils.ObjectReader;
41 import org.opendaylight.controller.sal.utils.ObjectWriter;
42 import org.opendaylight.controller.sal.utils.Status;
43 import org.opendaylight.controller.usermanager.AuthResponse;
44 import org.opendaylight.controller.usermanager.AuthenticatedUser;
45 import org.opendaylight.controller.usermanager.AuthorizationConfig;
46 import org.opendaylight.controller.usermanager.IAAAProvider;
47 import org.opendaylight.controller.usermanager.ISessionManager;
48 import org.opendaylight.controller.usermanager.IUserManager;
49 import org.opendaylight.controller.usermanager.ServerConfig;
50 import org.opendaylight.controller.usermanager.UserConfig;
51 import org.opendaylight.controller.usermanager.security.SessionManager;
52 import org.opendaylight.controller.usermanager.security.UserSecurityContextRepository;
54 import org.osgi.framework.BundleContext;
55 import org.osgi.framework.FrameworkUtil;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58 import org.springframework.security.authentication.AuthenticationProvider;
59 import org.springframework.security.authentication.AuthenticationServiceException;
60 import org.springframework.security.authentication.BadCredentialsException;
61 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
62 import org.springframework.security.core.Authentication;
63 import org.springframework.security.core.AuthenticationException;
64 import org.springframework.security.core.userdetails.User;
65 import org.springframework.security.core.userdetails.UserDetails;
66 import org.springframework.security.core.userdetails.UsernameNotFoundException;
67 import org.springframework.security.web.context.SecurityContextRepository;
70 * The internal implementation of the User Manager.
72 public class UserManagerImpl implements IUserManager, IObjectReader,
73 IConfigurationAware, CommandProvider, AuthenticationProvider {
74 private static final Logger logger = LoggerFactory
75 .getLogger(UserManagerImpl.class);
76 private static final String defaultAdmin = "admin";
77 private static final String defaultAdminPassword = "admin";
78 private static final String defaultAdminRole = UserLevel.NETWORKADMIN
80 private static final String ROOT = GlobalConstants.STARTUPHOME.toString();
81 private static final String SAVE = "save";
82 private static final String usersFileName = ROOT + "users.conf";
83 private static final String serversFileName = ROOT + "servers.conf";
84 private static final String authFileName = ROOT + "authorization.conf";
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 ConcurrentMap<Long, String> localUserListSaveConfigEvent,
92 remoteServerSaveConfigEvent, authorizationSaveConfigEvent;
93 private IClusterGlobalServices clusterGlobalService = null;
94 private SecurityContextRepository securityContextRepo = new UserSecurityContextRepository();
95 private IContainerAuthorization containerAuthorizationClient;
96 private Set<IResourceAuthorization> applicationAuthorizationClients;
97 private ISessionManager sessionMgr = new SessionManager();
99 public boolean addAAAProvider(IAAAProvider provider) {
100 if (provider == null || provider.getName() == null
101 || provider.getName().trim().isEmpty()) {
104 if (authProviders.get(provider.getName()) != null) {
108 authProviders.put(provider.getName(), provider);
112 public void removeAAAProvider(IAAAProvider provider) {
113 authProviders.remove(provider.getName());
116 public IAAAProvider getAAAProvider(String name) {
117 return authProviders.get(name);
121 public Set<String> getAAAProviderNames() {
122 return authProviders.keySet();
125 @SuppressWarnings("deprecation")
126 private void allocateCaches() {
127 this.applicationAuthorizationClients = Collections
128 .synchronizedSet(new HashSet<IResourceAuthorization>());
129 if (clusterGlobalService == null) {
130 logger.error("un-initialized clusterGlobalService, can't create cache");
135 clusterGlobalService.createCache("usermanager.localUserConfigList",
136 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
138 clusterGlobalService.createCache(
139 "usermanager.remoteServerConfigList",
140 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
142 clusterGlobalService.createCache(
143 "usermanager.authorizationConfList",
144 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
146 clusterGlobalService.createCache("usermanager.activeUsers",
147 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
149 clusterGlobalService.createCache(
150 "usermanager.localUserSaveConfigEvent",
151 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
153 clusterGlobalService.createCache(
154 "usermanager.remoteServerSaveConfigEvent",
155 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
157 clusterGlobalService.createCache(
158 "usermanager.authorizationSaveConfigEvent",
159 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
160 } catch (CacheConfigException cce) {
161 logger.error("Cache configuration invalid - check cache mode");
162 } catch (CacheExistException ce) {
163 logger.debug("Skipping cache creation as already present");
167 @SuppressWarnings({ "unchecked", "deprecation" })
168 private void retrieveCaches() {
169 if (clusterGlobalService == null) {
170 logger.error("un-initialized clusterService, can't retrieve cache");
174 activeUsers = (ConcurrentMap<String, AuthenticatedUser>) clusterGlobalService
175 .getCache("usermanager.activeUsers");
176 if (activeUsers == null) {
177 logger.error("Failed to get cache for activeUsers");
180 localUserConfigList = (ConcurrentMap<String, UserConfig>) clusterGlobalService
181 .getCache("usermanager.localUserConfigList");
182 if (localUserConfigList == null) {
183 logger.error("Failed to get cache for localUserConfigList");
186 remoteServerConfigList = (ConcurrentMap<String, ServerConfig>) clusterGlobalService
187 .getCache("usermanager.remoteServerConfigList");
188 if (remoteServerConfigList == null) {
189 logger.error("Failed to get cache for remoteServerConfigList");
192 authorizationConfList = (ConcurrentMap<String, AuthorizationConfig>) clusterGlobalService
193 .getCache("usermanager.authorizationConfList");
194 if (authorizationConfList == null) {
195 logger.error("Failed to get cache for authorizationConfList");
198 localUserListSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
199 .getCache("usermanager.localUserSaveConfigEvent");
200 if (localUserListSaveConfigEvent == null) {
201 logger.error("Failed to get cache for localUserSaveConfigEvent");
204 remoteServerSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
205 .getCache("usermanager.remoteServerSaveConfigEvent");
206 if (remoteServerSaveConfigEvent == null) {
207 logger.error("Failed to get cache for remoteServerSaveConfigEvent");
210 authorizationSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
211 .getCache("usermanager.authorizationSaveConfigEvent");
212 if (authorizationSaveConfigEvent == null) {
213 logger.error("Failed to get cache for authorizationSaveConfigEvent");
217 private void loadConfigurations() {
218 // To encode and decode user and server configuration objects
222 * Do not load local startup file if we already got the configurations
223 * synced from another cluster node
225 if (localUserConfigList.isEmpty()) {
228 if (remoteServerConfigList.isEmpty()) {
231 if (authorizationConfList.isEmpty()) {
236 private void loadSecurityKeys() {
240 private void checkDefaultNetworkAdmin() {
241 // If startup config is not there, it's old or it was deleted,
242 // need to add Default Admin
243 if (!localUserConfigList.containsKey(defaultAdmin)) {
244 List<String> roles = new ArrayList<String>(1);
245 roles.add(defaultAdminRole);
246 localUserConfigList.put(defaultAdmin, new UserConfig(defaultAdmin,
247 defaultAdminPassword, roles));
252 public AuthResultEnum authenticate(String userName, String password) {
253 IAAAProvider aaaClient;
254 AuthResponse rcResponse = null;
255 AuthenticatedUser result;
256 boolean remotelyAuthenticated = false;
257 boolean authorizationInfoIsPresent = false;
258 boolean authorized = false;
261 * Attempt remote authentication first if server is configured
263 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
264 String protocol = aaaServer.getProtocol();
265 aaaClient = this.getAAAProvider(protocol);
266 if (aaaClient != null) {
267 rcResponse = aaaClient.authService(userName, password,
268 aaaServer.getAddress(), aaaServer.getSecret());
269 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
271 "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
272 userName, aaaServer.getAddress());
273 remotelyAuthenticated = true;
275 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
277 "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
278 new Object[] { userName, aaaServer.getAddress(),
279 rcResponse.getStatus().toString() });
282 "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
283 new Object[] { userName, aaaServer.getAddress(),
284 rcResponse.getStatus().toString() });
289 if (!remotelyAuthenticated) {
290 UserConfig localUser = this.localUserConfigList.get(userName);
291 if (localUser == null) {
293 "Local Authentication Failed for User:\"{}\", Reason: "
294 + "user not found in Local Database", userName);
295 return (AuthResultEnum.AUTH_INVALID_LOC_USER);
297 rcResponse = localUser.authenticate(password);
298 if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
300 "Local Authentication Failed for User: \"{}\", Reason: {}",
301 userName, rcResponse.getStatus().toString());
303 return (rcResponse.getStatus());
305 logger.info("Local Authentication Succeeded for User: \"{}\"",
310 * Authentication succeeded
312 result = new AuthenticatedUser(userName);
315 * Extract attributes from response All the information we are
316 * interested in is in the first Cisco VSA (vendor specific attribute).
317 * Just process the first VSA and return
319 String attributes = (rcResponse.getData() != null && !rcResponse
320 .getData().isEmpty()) ? rcResponse.getData().get(0) : null;
323 * Check if the authorization information is present
325 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
328 * The AAA server was only used to perform the authentication Look for
329 * locally stored authorization info for this user If found, add the
330 * data to the rcResponse
332 if (remotelyAuthenticated && !authorizationInfoIsPresent) {
334 "No Remote Authorization Info provided by Server for User: \"{}\"",
337 "Looking for Local Authorization Info for User: \"{}\"",
340 AuthorizationConfig resource = authorizationConfList.get(userName);
341 if (resource != null) {
342 logger.info("Found Local Authorization Info for User: \"{}\"",
344 attributes = resource.getRolesString();
347 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
351 * Common response parsing for local & remote authenticated user Looking
352 * for authorized resources, detecting attributes' validity
354 if (authorizationInfoIsPresent) {
355 // Identifying the administrative role
356 result.setRoleList(attributes.split(" "));
359 logger.info("Not able to find Authorization Info for User: \"{}\"",
364 * Add profile for authenticated user
366 putUserInActiveList(userName, result);
368 logger.info("User \"{}\" authorized for the following role(s): {}",
369 userName, result.getUserRoles());
371 logger.info("User \"{}\" Not Authorized for any role ", userName);
374 return rcResponse.getStatus();
377 // Check in the attributes string whether or not authorization information
379 private boolean checkAuthorizationInfo(String attributes) {
380 return (attributes != null && !attributes.isEmpty());
383 private void putUserInActiveList(String user, AuthenticatedUser result) {
384 activeUsers.put(user, result);
387 private void removeUserFromActiveList(String user) {
388 if (!activeUsers.containsKey(user)) {
389 // as cookie persists in cache, we can get logout for unexisting
393 activeUsers.remove(user);
397 public Status saveLocalUserList() {
398 return saveLocalUserListInternal();
401 private Status saveLocalUserListInternal() {
402 ObjectWriter objWriter = new ObjectWriter();
403 return objWriter.write(new ConcurrentHashMap<String, UserConfig>(
404 localUserConfigList), usersFileName);
408 public Status saveAAAServerList() {
409 return saveAAAServerListInternal();
412 private Status saveAAAServerListInternal() {
413 ObjectWriter objWriter = new ObjectWriter();
414 return objWriter.write(new ConcurrentHashMap<String, ServerConfig>(
415 remoteServerConfigList), serversFileName);
419 public Status saveAuthorizationList() {
420 return saveAuthorizationListInternal();
423 private Status saveAuthorizationListInternal() {
424 ObjectWriter objWriter = new ObjectWriter();
425 return objWriter.write(
426 new ConcurrentHashMap<String, AuthorizationConfig>(
427 authorizationConfList), authFileName);
431 public Object readObject(ObjectInputStream ois)
432 throws FileNotFoundException, IOException, ClassNotFoundException {
433 // Perform the class deserialization locally, from inside the package
434 // where the class is defined
435 return ois.readObject();
438 @SuppressWarnings("unchecked")
439 private void loadUserConfig() {
440 ObjectReader objReader = new ObjectReader();
441 ConcurrentMap<String, UserConfig> confList = (ConcurrentMap<String, UserConfig>) objReader
442 .read(this, usersFileName);
444 if (confList == null) {
448 for (UserConfig conf : confList.values()) {
449 addRemoveLocalUserInternal(conf, false);
453 @SuppressWarnings("unchecked")
454 private void loadServerConfig() {
455 ObjectReader objReader = new ObjectReader();
456 ConcurrentMap<String, ServerConfig> confList = (ConcurrentMap<String, ServerConfig>) objReader
457 .read(this, serversFileName);
459 if (confList == null) {
463 for (ServerConfig conf : confList.values()) {
468 @SuppressWarnings("unchecked")
469 private void loadAuthConfig() {
470 ObjectReader objReader = new ObjectReader();
471 ConcurrentMap<String, AuthorizationConfig> confList = (ConcurrentMap<String, AuthorizationConfig>) objReader
472 .read(this, authFileName);
474 if (confList == null) {
478 for (AuthorizationConfig conf : confList.values()) {
484 * Interaction with GUI START
486 private Status addRemoveLocalUser(UserConfig AAAconf, boolean delete) {
487 // UserConfig Validation check
488 Status validCheck = AAAconf.validate();
489 if (!validCheck.isSuccess()) {
493 String user = AAAconf.getUser();
495 // Check default admin user
496 if (user.equals(UserManagerImpl.defaultAdmin)) {
497 String msg = "Invalid Request: Default Network Admin User cannot be " + ((delete)? "removed" : "added");
499 return new Status(StatusCode.NOTALLOWED, msg);
502 // Check user presence/conflict
503 StatusCode statusCode = null;
504 String reason = null;
505 if (delete && !localUserConfigList.containsKey(user)) {
506 reason = "not found";
507 statusCode = StatusCode.NOTFOUND;
508 } else if (!delete && localUserConfigList.containsKey(user)) {
509 reason = "already present";
510 statusCode = StatusCode.CONFLICT;
512 if (statusCode != null) {
513 String msg = String.format("User %s %s in configuration database", user, reason);
515 return new Status(statusCode, msg);
518 return addRemoveLocalUserInternal(AAAconf, delete);
521 private Status addRemoveLocalUserInternal(UserConfig AAAconf, boolean delete) {
522 // Update Config database
524 localUserConfigList.remove(AAAconf.getUser());
526 * A user account has been removed form local database, we assume
527 * admin does not want this user to stay connected, in case he has
528 * an open session. So we clean the active list as well.
530 removeUserFromActiveList(AAAconf.getUser());
532 localUserConfigList.put(AAAconf.getUser(), AAAconf);
535 return new Status(StatusCode.SUCCESS);
538 private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
540 if (!AAAconf.isValid()) {
541 String msg = "Invalid Server configuration";
543 return new Status(StatusCode.BADREQUEST, msg);
546 // Update configuration database
548 remoteServerConfigList.remove(AAAconf.getAddress());
550 remoteServerConfigList.put(AAAconf.getAddress(), AAAconf);
553 return new Status(StatusCode.SUCCESS);
556 private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
557 Status configCheck = AAAconf.validate();
558 if (!configCheck.isSuccess()) {
559 String msg = "Invalid Authorization configuration: "
560 + configCheck.getDescription();
562 return new Status(StatusCode.BADREQUEST, msg);
565 // Update configuration database
567 authorizationConfList.remove(AAAconf.getUser());
569 authorizationConfList.put(AAAconf.getUser(), AAAconf);
572 return new Status(StatusCode.SUCCESS);
576 public Status addLocalUser(UserConfig AAAconf) {
577 return addRemoveLocalUser(AAAconf, false);
581 public Status removeLocalUser(UserConfig AAAconf) {
582 return addRemoveLocalUser(AAAconf, true);
586 public Status removeLocalUser(String userName) {
587 if (userName == null || userName.trim().isEmpty()) {
588 return new Status(StatusCode.BADREQUEST, "Invalid user name");
591 if (!localUserConfigList.containsKey(userName)) {
592 return new Status(StatusCode.NOTFOUND, "User does not exist");
595 return addRemoveLocalUser(localUserConfigList.get(userName), true);
599 public Status addAAAServer(ServerConfig AAAconf) {
600 return addRemoveAAAServer(AAAconf, false);
604 public Status removeAAAServer(ServerConfig AAAconf) {
605 return addRemoveAAAServer(AAAconf, true);
609 public Status addAuthInfo(AuthorizationConfig AAAconf) {
610 return addRemoveAuthInfo(AAAconf, false);
614 public Status removeAuthInfo(AuthorizationConfig AAAconf) {
615 return addRemoveAuthInfo(AAAconf, true);
619 public List<UserConfig> getLocalUserList() {
620 return new ArrayList<UserConfig>(localUserConfigList.values());
624 public List<ServerConfig> getAAAServerList() {
625 return new ArrayList<ServerConfig>(remoteServerConfigList.values());
629 public List<AuthorizationConfig> getAuthorizationList() {
630 return new ArrayList<AuthorizationConfig>(
631 authorizationConfList.values());
635 public Status changeLocalUserPassword(String user, String curPassword,
636 String newPassword) {
637 UserConfig targetConfigEntry = null;
639 // update configuration entry
640 targetConfigEntry = localUserConfigList.get(user);
641 if (targetConfigEntry == null) {
642 return new Status(StatusCode.NOTFOUND, "User not found");
644 Status status = targetConfigEntry
645 .update(curPassword, newPassword, null);
646 if (!status.isSuccess()) {
649 // Trigger cluster update
650 localUserConfigList.put(user, targetConfigEntry);
652 logger.info("Password changed for User \"{}\"", user);
658 public void userLogout(String userName) {
659 // TODO: if user was authenticated through AAA server, send
660 // Acct-Status-Type=stop message to server with logout as reason
661 removeUserFromActiveList(userName);
662 logger.info("User \"{}\" logged out", userName);
666 * This function will get called by http session mgr when session times out
669 public void userTimedOut(String userName) {
670 // TODO: if user was authenticated through AAA server, send
671 // Acct-Status-Type=stop message to server with timeout as reason
672 removeUserFromActiveList(userName);
673 logger.info("User \"{}\" timed out", userName);
677 public String getAccessDate(String user) {
678 return this.activeUsers.get(user).getAccessDate();
682 public synchronized Map<String, List<String>> getUserLoggedIn() {
683 Map<String, List<String>> loggedInList = new HashMap<String, List<String>>();
684 for (Map.Entry<String, AuthenticatedUser> user : activeUsers.entrySet()) {
685 String userNameShow = user.getKey();
686 loggedInList.put(userNameShow, user.getValue().getUserRoles());
691 public void _umAddUser(CommandInterpreter ci) {
692 String userName = ci.nextArgument();
693 String password = ci.nextArgument();
694 String role = ci.nextArgument();
696 List<String> roles = new ArrayList<String>();
697 while (role != null) {
698 if (!role.trim().isEmpty()) {
701 role = ci.nextArgument();
704 if (userName == null || userName.trim().isEmpty() || password == null
705 || password.trim().isEmpty() || roles == null
706 || roles.isEmpty()) {
707 ci.println("Invalid Arguments");
708 ci.println("umAddUser <user_name> <password> <user_role>");
711 ci.print(this.addLocalUser(new UserConfig(userName, password, roles)));
714 public void _umRemUser(CommandInterpreter ci) {
715 String userName = ci.nextArgument();
717 if (userName == null || userName.trim().isEmpty()) {
718 ci.println("Invalid Arguments");
719 ci.println("umRemUser <user_name>");
722 UserConfig target = localUserConfigList.get(userName);
723 if (target == null) {
724 ci.println("User not found");
727 ci.println(this.removeLocalUser(target));
730 public void _umGetUsers(CommandInterpreter ci) {
731 for (UserConfig conf : this.getLocalUserList()) {
732 ci.println(conf.getUser() + " " + conf.getRoles());
736 public void _addAAAServer(CommandInterpreter ci) {
737 String server = ci.nextArgument();
738 String secret = ci.nextArgument();
739 String protocol = ci.nextArgument();
741 if (server == null || secret == null || protocol == null) {
742 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
745 ServerConfig s = new ServerConfig(server, secret, protocol);
749 public void _removeAAAServer(CommandInterpreter ci) {
750 String server = ci.nextArgument();
751 String secret = ci.nextArgument();
752 String protocol = ci.nextArgument();
754 if (server == null || secret == null || protocol == null) {
755 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
758 ServerConfig s = new ServerConfig(server, secret, protocol);
762 public void _printAAAServers(CommandInterpreter ci) {
763 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
764 ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
769 public String getHelp() {
770 StringBuffer help = new StringBuffer();
771 return help.toString();
774 void setClusterGlobalService(IClusterGlobalServices s) {
775 logger.debug("Cluster Service Global set");
776 this.clusterGlobalService = s;
779 void unsetClusterGlobalService(IClusterGlobalServices s) {
780 if (this.clusterGlobalService == s) {
781 logger.debug("Cluster Service Global removed!");
782 this.clusterGlobalService = null;
786 void unsetContainerAuthClient(IContainerAuthorization s) {
787 if (this.containerAuthorizationClient == s) {
788 this.containerAuthorizationClient = null;
792 void setContainerAuthClient(IContainerAuthorization s) {
793 this.containerAuthorizationClient = s;
796 void setAppAuthClient(IResourceAuthorization s) {
797 this.applicationAuthorizationClients.add(s);
800 void unsetAppAuthClient(IResourceAuthorization s) {
801 this.applicationAuthorizationClients.remove(s);
805 * Function called by the dependency manager when all the required
806 * dependencies are satisfied
813 * Function called by the dependency manager when at least one dependency
814 * become unsatisfied or when the component is shutting down because for
815 * example bundle is being stopped.
822 * Function called by dependency manager after "init ()" is called and after
823 * the services provided by the class are registered in the service registry
827 authProviders = new ConcurrentHashMap<String, IAAAProvider>();
828 // Instantiate cluster synced variables
832 // Read startup configuration and populate databases
833 loadConfigurations();
835 // Make sure default Network Admin account is there
836 checkDefaultNetworkAdmin();
837 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
839 bundleContext.registerService(CommandProvider.class.getName(), this,
844 * Function called by the dependency manager before the services exported by
845 * the component are unregistered, this will be followed by a "destroy ()"
853 public List<String> getUserRoles(String userName) {
854 List<String> roles = null;
855 if (userName != null) {
857 * First look in active users then in local configured users,
858 * finally in local authorized users
860 if (activeUsers.containsKey(userName)) {
861 roles = activeUsers.get(userName).getUserRoles();
862 } else if (localUserConfigList.containsKey(userName)) {
863 roles = localUserConfigList.get(userName).getRoles();
864 } else if (authorizationConfList.containsKey(userName)) {
865 roles = authorizationConfList.get(userName).getRoles();
868 return (roles == null) ? new ArrayList<String>(0) : roles;
872 public UserLevel getUserLevel(String username) {
873 // Returns the highest controller user level for the passed user
874 List<String> rolesNames = getUserRoles(username);
876 if (rolesNames.isEmpty()) {
877 return UserLevel.NOUSER;
880 // Check against the well known controller roles first
881 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
882 return UserLevel.SYSTEMADMIN;
884 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
885 return UserLevel.NETWORKADMIN;
887 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
888 return UserLevel.NETWORKOPERATOR;
890 // Check if container user now
891 if (containerAuthorizationClient != null) {
892 for (String roleName : rolesNames) {
893 if (containerAuthorizationClient.isApplicationRole(roleName)) {
894 return UserLevel.CONTAINERUSER;
898 // Finally check if application user
899 if (applicationAuthorizationClients != null) {
900 for (String roleName : rolesNames) {
901 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
902 if (client.isApplicationRole(roleName)) {
903 return UserLevel.APPUSER;
908 return UserLevel.NOUSER;
913 public List<UserLevel> getUserLevels(String username) {
914 // Returns the controller user levels for the passed user
915 List<String> rolesNames = getUserRoles(username);
916 List<UserLevel> levels = new ArrayList<UserLevel>();
918 if (rolesNames.isEmpty()) {
922 // Check against the well known controller roles first
923 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
924 levels.add(UserLevel.SYSTEMADMIN);
926 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
927 levels.add(UserLevel.NETWORKADMIN);
929 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
930 levels.add(UserLevel.NETWORKOPERATOR);
932 // Check if container user now
933 if (containerAuthorizationClient != null) {
934 for (String roleName : rolesNames) {
935 if (containerAuthorizationClient.isApplicationRole(roleName)) {
936 levels.add(UserLevel.CONTAINERUSER);
941 // Finally check if application user
942 if (applicationAuthorizationClients != null) {
943 for (String roleName : rolesNames) {
944 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
945 if (client.isApplicationRole(roleName)) {
946 levels.add(UserLevel.APPUSER);
956 public Status saveConfiguration() {
957 boolean success = true;
958 Status ret = saveLocalUserList();
959 if (!ret.isSuccess()) {
962 ret = saveAAAServerList();
963 if (!ret.isSuccess()) {
966 ret = saveAuthorizationList();
967 if (!ret.isSuccess()) {
972 return new Status(StatusCode.SUCCESS);
975 return new Status(StatusCode.INTERNALERROR, "Failed to save user configurations");
979 public UserDetails loadUserByUsername(String username)
980 throws UsernameNotFoundException {
981 AuthenticatedUser user = activeUsers.get(username);
984 boolean enabled = true;
985 boolean accountNonExpired = true;
986 boolean credentialsNonExpired = true;
987 boolean accountNonLocked = true;
989 return new User(username, localUserConfigList.get(username)
990 .getPassword(), enabled, accountNonExpired,
991 credentialsNonExpired, accountNonLocked,
992 user.getGrantedAuthorities(getUserLevel(username)));
994 throw new UsernameNotFoundException("User not found " + username);
999 public boolean supports(Class<?> authentication) {
1000 return UsernamePasswordAuthenticationToken.class
1001 .isAssignableFrom(authentication);
1006 public SecurityContextRepository getSecurityContextRepo() {
1007 return securityContextRepo;
1010 public void setSecurityContextRepo(
1011 SecurityContextRepository securityContextRepo) {
1012 this.securityContextRepo = securityContextRepo;
1016 public Authentication authenticate(Authentication authentication)
1017 throws AuthenticationException {
1019 if (StringUtils.isBlank((String) authentication.getCredentials())
1020 || StringUtils.isBlank((String) authentication.getPrincipal())) {
1021 throw new BadCredentialsException(
1022 "Username or credentials did not match");
1025 AuthResultEnum result = authenticate(
1026 (String) authentication.getPrincipal(),
1027 (String) authentication.getCredentials());
1028 if (result.equals(AuthResultEnum.AUTHOR_PASS)
1029 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
1030 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
1032 AuthenticatedUser user = activeUsers.get(authentication
1033 .getPrincipal().toString());
1036 throw new AuthenticationServiceException(
1037 "Authentication Failure");
1040 authentication = new UsernamePasswordAuthenticationToken(
1041 authentication.getPrincipal(),
1042 authentication.getCredentials(),
1043 user.getGrantedAuthorities(getUserLevel(authentication
1045 return authentication;
1048 throw new BadCredentialsException(
1049 "Username or credentials did not match");
1054 // Following are setters for use in unit testing
1055 void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1057 this.localUserConfigList = ucl;
1061 void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1063 this.remoteServerConfigList = scl;
1067 void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1069 this.authorizationConfList = acl;
1073 void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1075 this.activeUsers = au;
1079 void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1081 this.authProviders = ap;
1086 public ISessionManager getSessionManager() {
1087 return this.sessionMgr;
1090 public void setSessionMgr(ISessionManager sessionMgr) {
1091 this.sessionMgr = sessionMgr;
1095 public String getPassword(String username) {
1096 return localUserConfigList.get(username).getPassword();
1100 public boolean isRoleInUse(String role) {
1101 if (role == null || role.isEmpty()) {
1104 // Check against controller roles
1105 if (role.equals(UserLevel.SYSTEMADMIN.toString())
1106 || role.equals(UserLevel.NETWORKADMIN.toString())
1107 || role.equals(UserLevel.NETWORKOPERATOR.toString())) {
1110 // Check if container roles
1111 if (containerAuthorizationClient != null) {
1112 if (containerAuthorizationClient.isApplicationRole(role)) {
1116 // Finally if application role
1117 if (applicationAuthorizationClients != null) {
1118 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
1119 if (client.isApplicationRole(role)) {