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.Date;
17 import java.util.EnumSet;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
23 import java.util.concurrent.ConcurrentHashMap;
24 import java.util.concurrent.ConcurrentMap;
26 import org.apache.commons.lang3.StringUtils;
27 import org.eclipse.osgi.framework.console.CommandInterpreter;
28 import org.eclipse.osgi.framework.console.CommandProvider;
29 import org.opendaylight.controller.clustering.services.CacheConfigException;
30 import org.opendaylight.controller.clustering.services.CacheExistException;
31 import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
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.IAAAProvider;
47 import org.opendaylight.controller.usermanager.ISessionManager;
48 import org.opendaylight.controller.usermanager.IUserManager;
49 import org.opendaylight.controller.usermanager.security.SessionManager;
50 import org.opendaylight.controller.usermanager.security.UserSecurityContextRepository;
51 import org.osgi.framework.BundleContext;
52 import org.osgi.framework.FrameworkUtil;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55 import org.springframework.security.authentication.AuthenticationProvider;
56 import org.springframework.security.authentication.AuthenticationServiceException;
57 import org.springframework.security.authentication.BadCredentialsException;
58 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
59 import org.springframework.security.core.Authentication;
60 import org.springframework.security.core.AuthenticationException;
61 import org.springframework.security.core.userdetails.User;
62 import org.springframework.security.core.userdetails.UserDetails;
63 import org.springframework.security.core.userdetails.UsernameNotFoundException;
64 import org.springframework.security.web.context.SecurityContextRepository;
67 * The internal implementation of the User Manager.
69 public class UserManagerImpl implements IUserManager, IObjectReader,
70 IConfigurationAware, ICacheUpdateAware<Long, String>, CommandProvider,
71 AuthenticationProvider {
72 private static final Logger logger = LoggerFactory
73 .getLogger(UserManagerImpl.class);
74 private static final String defaultAdmin = "admin";
75 private static final String defaultAdminPassword = "admin";
76 private static final String defaultAdminRole = UserLevel.NETWORKADMIN
78 private static final String ROOT = GlobalConstants.STARTUPHOME.toString();
79 private static final String SAVE = "save";
80 private static final String usersFileName = ROOT + "users.conf";
81 private static final String serversFileName = ROOT + "servers.conf";
82 private static final String authFileName = ROOT + "authorization.conf";
83 private ConcurrentMap<String, UserConfig> localUserConfigList;
84 private ConcurrentMap<String, ServerConfig> remoteServerConfigList;
85 private ConcurrentMap<String, AuthorizationConfig> authorizationConfList; // local
92 private ConcurrentMap<String, AuthenticatedUser> activeUsers;
93 private ConcurrentMap<String, IAAAProvider> authProviders;
94 private ConcurrentMap<Long, String> localUserListSaveConfigEvent,
95 remoteServerSaveConfigEvent, authorizationSaveConfigEvent;
96 private IClusterGlobalServices clusterGlobalService = null;
97 private SecurityContextRepository securityContextRepo = new UserSecurityContextRepository();
98 private IContainerAuthorization containerAuthorizationClient;
99 private Set<IResourceAuthorization> applicationAuthorizationClients;
100 private ISessionManager sessionMgr = new SessionManager();
102 public boolean addAAAProvider(IAAAProvider provider) {
103 if (provider == null || provider.getName() == null
104 || provider.getName().trim().isEmpty()) {
107 if (authProviders.get(provider.getName()) != null) {
111 authProviders.put(provider.getName(), provider);
115 public void removeAAAProvider(IAAAProvider provider) {
116 authProviders.remove(provider.getName());
119 public IAAAProvider getAAAProvider(String name) {
120 return authProviders.get(name);
123 public Set<String> getAAAProviderNames() {
124 return authProviders.keySet();
127 @SuppressWarnings("deprecation")
128 private void allocateCaches() {
129 this.applicationAuthorizationClients = Collections
130 .synchronizedSet(new HashSet<IResourceAuthorization>());
131 if (clusterGlobalService == null) {
132 logger.error("un-initialized clusterGlobalService, can't create cache");
137 clusterGlobalService.createCache("usermanager.localUserConfigList",
138 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
140 clusterGlobalService.createCache(
141 "usermanager.remoteServerConfigList",
142 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
144 clusterGlobalService.createCache(
145 "usermanager.authorizationConfList",
146 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
148 clusterGlobalService.createCache("usermanager.activeUsers",
149 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
151 clusterGlobalService.createCache(
152 "usermanager.localUserSaveConfigEvent",
153 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
155 clusterGlobalService.createCache(
156 "usermanager.remoteServerSaveConfigEvent",
157 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
159 clusterGlobalService.createCache(
160 "usermanager.authorizationSaveConfigEvent",
161 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
162 } catch (CacheConfigException cce) {
163 logger.error("\nCache configuration invalid - check cache mode");
164 } catch (CacheExistException ce) {
165 logger.error("\nCache already exits - destroy and recreate if needed");
169 @SuppressWarnings({ "unchecked", "deprecation" })
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("\nFailed to get cache for activeUsers");
182 localUserConfigList = (ConcurrentMap<String, UserConfig>) clusterGlobalService
183 .getCache("usermanager.localUserConfigList");
184 if (localUserConfigList == null) {
185 logger.error("\nFailed to get cache for localUserConfigList");
188 remoteServerConfigList = (ConcurrentMap<String, ServerConfig>) clusterGlobalService
189 .getCache("usermanager.remoteServerConfigList");
190 if (remoteServerConfigList == null) {
191 logger.error("\nFailed to get cache for remoteServerConfigList");
194 authorizationConfList = (ConcurrentMap<String, AuthorizationConfig>) clusterGlobalService
195 .getCache("usermanager.authorizationConfList");
196 if (authorizationConfList == null) {
197 logger.error("\nFailed to get cache for authorizationConfList");
200 localUserListSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
201 .getCache("usermanager.localUserSaveConfigEvent");
202 if (localUserListSaveConfigEvent == null) {
203 logger.error("\nFailed to get cache for localUserSaveConfigEvent");
206 remoteServerSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
207 .getCache("usermanager.remoteServerSaveConfigEvent");
208 if (remoteServerSaveConfigEvent == null) {
209 logger.error("\nFailed to get cache for remoteServerSaveConfigEvent");
212 authorizationSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
213 .getCache("usermanager.authorizationSaveConfigEvent");
214 if (authorizationSaveConfigEvent == null) {
215 logger.error("\nFailed to get cache for authorizationSaveConfigEvent");
219 private void loadConfigurations() {
220 // To encode and decode user and server configuration objects
224 * Do not load local startup file if we already got the configurations
225 * synced from another cluster node
227 if (localUserConfigList.isEmpty()) {
230 if (remoteServerConfigList.isEmpty()) {
233 if (authorizationConfList.isEmpty()) {
238 private void loadSecurityKeys() {
242 private void checkDefaultNetworkAdmin() {
243 // If startup config is not there, it's old or it was deleted,
244 // need to add Default Admin
245 if (!localUserConfigList.containsKey(defaultAdmin)) {
246 localUserConfigList.put(defaultAdmin, new UserConfig(defaultAdmin,
247 defaultAdminPassword, defaultAdminRole));
252 public AuthResultEnum authenticate(String userName, String password) {
253 IAAAProvider aaaClient;
254 AuthResponse rcResponse = null;
255 AuthenticatedUser result;
256 String[] adminRoles = null;
257 boolean remotelyAuthenticated = false;
258 boolean authorizationInfoIsPresent = false;
259 boolean authorized = false;
262 * Attempt remote authentication first if server is configured
264 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
265 String protocol = aaaServer.getProtocol();
266 aaaClient = this.getAAAProvider(protocol);
267 if (aaaClient != null) {
268 rcResponse = aaaClient.authService(userName, password,
269 aaaServer.getAddress(), aaaServer.getSecret());
270 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
272 "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
273 userName, aaaServer.getAddress());
274 remotelyAuthenticated = true;
276 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
278 "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
279 new Object[] {userName, aaaServer.getAddress(),
280 rcResponse.getStatus().toString()});
283 "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
284 new Object[] {userName, aaaServer.getAddress(),
285 rcResponse.getStatus().toString()});
290 if (!remotelyAuthenticated) {
291 UserConfig localUser = this.localUserConfigList.get(userName);
292 if (localUser == null) {
294 "Local Authentication Failed for User:\"{}\", Reason: "
295 + "user not found in Local Database", userName);
296 return (AuthResultEnum.AUTH_INVALID_LOC_USER);
298 rcResponse = localUser.authenticate(password);
299 if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
301 "Local Authentication Failed for User: \"{}\", Reason: {}",
302 userName, rcResponse.getStatus().toString());
304 return (rcResponse.getStatus());
306 logger.info("Local Authentication Succeeded for User: \"{}\"",
311 * Authentication succeeded
313 result = new AuthenticatedUser(userName);
316 * Extract attributes from response All the information we are
317 * interested in is in the first Cisco VSA (vendor specific attribute).
318 * Just process the first VSA and return
320 String attributes = (rcResponse.getData() != null && !rcResponse
321 .getData().isEmpty()) ? rcResponse.getData().get(0) : null;
324 * Check if the authorization information is present
326 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
329 * The AAA server was only used to perform the authentication Look for
330 * locally stored authorization info for this user If found, add the
331 * data to the rcResponse
333 if (remotelyAuthenticated && !authorizationInfoIsPresent) {
335 "No Remote Authorization Info provided by Server for User: \"{}\"",
338 "Looking for Local Authorization Info for User: \"{}\"",
341 AuthorizationConfig resource = authorizationConfList.get(userName);
342 if (resource != null) {
343 logger.info("Found Local Authorization Info for User: \"{}\"",
345 attributes = resource.getRolesData();
348 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
352 * Common response parsing for local & remote authenticated user Looking
353 * for authorized resources, detecting attributes' validity
355 if (authorizationInfoIsPresent) {
356 // Identifying the administrative role
357 adminRoles = attributes.split(" ");
358 result.setRoleList(adminRoles);
361 logger.info("Not able to find Authorization Info for User: \"{}\"",
366 * Add profile for authenticated user
368 putUserInActiveList(userName, result);
370 logger.info("User \"{}\" authorized for the following role(s): {}",
371 userName, result.getUserRoles());
373 logger.info("User \"{}\" Not Authorized for any role ", userName);
376 return rcResponse.getStatus();
379 // Check in the attributes string whether or not authorization information
381 private boolean checkAuthorizationInfo(String attributes) {
382 return (attributes != null && !attributes.isEmpty());
385 private void putUserInActiveList(String user, AuthenticatedUser result) {
386 activeUsers.put(user, result);
389 private void removeUserFromActiveList(String user) {
390 if (!activeUsers.containsKey(user)) {
391 // as cookie persists in cache, we can get logout for unexisting
395 activeUsers.remove(user);
398 public Status saveLocalUserList() {
399 // Publish the save config event to the cluster nodes
400 localUserListSaveConfigEvent.put(new Date().getTime(), SAVE);
401 return saveLocalUserListInternal();
404 private Status saveLocalUserListInternal() {
405 ObjectWriter objWriter = new ObjectWriter();
406 return objWriter.write(new ConcurrentHashMap<String, UserConfig>(
407 localUserConfigList), usersFileName);
410 public Status saveAAAServerList() {
411 // Publish the save config event to the cluster nodes
412 remoteServerSaveConfigEvent.put(new Date().getTime(), SAVE);
413 return saveAAAServerListInternal();
416 private Status saveAAAServerListInternal() {
417 ObjectWriter objWriter = new ObjectWriter();
418 return objWriter.write(new ConcurrentHashMap<String, ServerConfig>(
419 remoteServerConfigList), serversFileName);
422 public Status saveAuthorizationList() {
423 // Publish the save config event to the cluster nodes
424 authorizationSaveConfigEvent.put(new Date().getTime(), SAVE);
425 return saveAuthorizationListInternal();
428 private Status saveAuthorizationListInternal() {
429 ObjectWriter objWriter = new ObjectWriter();
430 return objWriter.write(
431 new ConcurrentHashMap<String, AuthorizationConfig>(
432 authorizationConfList), authFileName);
436 public Object readObject(ObjectInputStream ois)
437 throws FileNotFoundException, IOException, ClassNotFoundException {
438 // Perform the class deserialization locally, from inside the package
439 // where the class is defined
440 return ois.readObject();
443 @SuppressWarnings("unchecked")
444 private void loadUserConfig() {
445 ObjectReader objReader = new ObjectReader();
446 ConcurrentMap<String, UserConfig> confList = (ConcurrentMap<String, UserConfig>) objReader
447 .read(this, usersFileName);
449 if (confList == null) {
453 for (UserConfig conf : confList.values()) {
458 @SuppressWarnings("unchecked")
459 private void loadServerConfig() {
460 ObjectReader objReader = new ObjectReader();
461 ConcurrentMap<String, ServerConfig> confList = (ConcurrentMap<String, ServerConfig>) objReader
462 .read(this, serversFileName);
464 if (confList == null) {
468 for (ServerConfig conf : confList.values()) {
473 @SuppressWarnings("unchecked")
474 private void loadAuthConfig() {
475 ObjectReader objReader = new ObjectReader();
476 ConcurrentMap<String, AuthorizationConfig> confList = (ConcurrentMap<String, AuthorizationConfig>) objReader
477 .read(this, authFileName);
479 if (confList == null) {
483 for (AuthorizationConfig conf : confList.values()) {
489 * Interaction with GUI START
491 public Status addRemoveLocalUser(UserConfig AAAconf, boolean delete) {
492 // UserConfig Validation check
493 Status validCheck = AAAconf.validate();
494 if (!validCheck.isSuccess()) {
498 // Update Config database
500 if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
501 String msg = "Invalid Request: Default Network Admin User "
502 + "cannot be deleted";
504 return new Status(StatusCode.NOTALLOWED, msg);
506 localUserConfigList.remove(AAAconf.getUser());
508 if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
509 String msg = "Invalid Request: Default Network Admin User "
512 return new Status(StatusCode.NOTALLOWED, msg);
514 localUserConfigList.put(AAAconf.getUser(), AAAconf);
517 return new Status(StatusCode.SUCCESS, null);
520 private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
522 if (!AAAconf.isValid()) {
523 String msg = "Invalid Server configuration";
525 return new Status(StatusCode.BADREQUEST, msg);
528 // Update configuration database
530 remoteServerConfigList.remove(AAAconf.getAddress());
532 remoteServerConfigList.put(AAAconf.getAddress(), AAAconf);
535 return new Status(StatusCode.SUCCESS, null);
538 private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
539 Status configCheck = AAAconf.validate();
540 if (!configCheck.isSuccess()) {
541 String msg = "Invalid Authorization configuration: "
542 + configCheck.getDescription();
544 return new Status(StatusCode.BADREQUEST, msg);
547 // Update configuration database
549 authorizationConfList.remove(AAAconf.getUser());
551 authorizationConfList.put(AAAconf.getUser(), AAAconf);
554 return new Status(StatusCode.SUCCESS, null);
558 public Status addLocalUser(UserConfig AAAconf) {
559 return addRemoveLocalUser(AAAconf, false);
563 public Status removeLocalUser(UserConfig AAAconf) {
564 return addRemoveLocalUser(AAAconf, true);
568 public Status removeLocalUser(String userName) {
569 if (userName == null || userName.trim().isEmpty()) {
570 return new Status(StatusCode.BADREQUEST, "Invalid user name");
572 if (!localUserConfigList.containsKey(userName)) {
573 return new Status(StatusCode.NOTFOUND, "User does not exist");
575 return addRemoveLocalUser(localUserConfigList.get(userName), true);
579 public Status addAAAServer(ServerConfig AAAconf) {
580 return addRemoveAAAServer(AAAconf, false);
584 public Status removeAAAServer(ServerConfig AAAconf) {
585 return addRemoveAAAServer(AAAconf, true);
589 public Status addAuthInfo(AuthorizationConfig AAAconf) {
590 return addRemoveAuthInfo(AAAconf, false);
594 public Status removeAuthInfo(AuthorizationConfig AAAconf) {
595 return addRemoveAuthInfo(AAAconf, true);
599 public List<UserConfig> getLocalUserList() {
600 return new ArrayList<UserConfig>(localUserConfigList.values());
604 public List<ServerConfig> getAAAServerList() {
605 return new ArrayList<ServerConfig>(remoteServerConfigList.values());
609 public List<AuthorizationConfig> getAuthorizationList() {
610 return new ArrayList<AuthorizationConfig>(
611 authorizationConfList.values());
615 public Status changeLocalUserPassword(String user, String curPassword,
616 String newPassword) {
617 UserConfig targetConfigEntry = null;
619 // update configuration entry
620 targetConfigEntry = localUserConfigList.get(user);
621 if (targetConfigEntry == null) {
622 return new Status(StatusCode.NOTFOUND, "User not found");
624 if (false == targetConfigEntry.update(curPassword, newPassword, null)) {
625 return new Status(StatusCode.BADREQUEST,
626 "Current password is incorrect");
628 localUserConfigList.put(user, targetConfigEntry); // trigger cluster
631 logger.info("Password changed for User \"{}\"", user);
633 return new Status(StatusCode.SUCCESS, null);
637 public void userLogout(String userName) {
638 // TODO: if user was authenticated through AAA server, send
639 // Acct-Status-Type=stop message to server with logout as reason
640 removeUserFromActiveList(userName);
641 logger.info("User \"{}\" logged out", userName);
645 * This function will get called by http session mgr when session times out
648 public void userTimedOut(String userName) {
649 // TODO: if user was authenticated through AAA server, send
650 // Acct-Status-Type=stop message to server with timeout as reason
651 removeUserFromActiveList(userName);
652 logger.info("User \"{}\" timed out", userName);
656 public String getAccessDate(String user) {
657 return this.activeUsers.get(user).getAccessDate();
661 public synchronized Map<String, List<String>> getUserLoggedIn() {
662 Map<String, List<String>> loggedInList = new HashMap<String, List<String>>();
663 for (Map.Entry<String, AuthenticatedUser> user : activeUsers.entrySet()) {
664 String userNameShow = user.getKey();
665 loggedInList.put(userNameShow, user.getValue().getUserRoles());
671 * Interaction with GUI END
675 * Cluster notifications
679 public void entryCreated(Long key, String cacheName, boolean originLocal) {
680 // don't react on this event
684 public void entryUpdated(Long key, String new_value, String cacheName,
685 boolean originLocal) {
686 if (cacheName.equals("localUserSaveConfigEvent")) {
687 this.saveLocalUserListInternal();
688 } else if (cacheName.equals("remoteServerSaveConfigEvent")) {
689 this.saveAAAServerListInternal();
690 } else if (cacheName.equals("authorizationSaveConfigEvent")) {
691 this.saveAuthorizationListInternal();
696 public void entryDeleted(Long key, String cacheName, boolean originLocal) {
697 // don't react on this event
700 public void _umAddUser(CommandInterpreter ci) {
701 String userName = ci.nextArgument();
702 String password = ci.nextArgument();
703 String role = ci.nextArgument();
705 if (userName == null || userName.trim().isEmpty() || password == null
706 || password.trim().isEmpty() || role == null
707 || role.trim().isEmpty()) {
708 ci.println("Invalid Arguments");
709 ci.println("umAddUser <user_name> <password> <user_role>");
712 this.addLocalUser(new UserConfig(userName, password, role));
715 public void _umRemUser(CommandInterpreter ci) {
716 String userName = ci.nextArgument();
717 String password = ci.nextArgument();
718 String role = ci.nextArgument();
720 if (userName == null || userName.trim().isEmpty() || password == null
721 || password.trim().isEmpty() || role == null
722 || role.trim().isEmpty()) {
723 ci.println("Invalid Arguments");
724 ci.println("umRemUser <user_name> <password> <user_role>");
727 this.removeLocalUser(new UserConfig(userName, password, role));
730 public void _umGetUsers(CommandInterpreter ci) {
731 for (UserConfig conf : this.getLocalUserList()) {
732 ci.println(conf.getUser() + " " + conf.getRole());
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 if (userName == null) {
855 return new ArrayList<String>(0);
857 AuthenticatedUser locatedUser = activeUsers.get(userName);
858 return (locatedUser == null) ? new ArrayList<String>(0) : locatedUser
863 public UserLevel getUserLevel(String username) {
864 // Returns the controller well-know user level for the passed user
865 String roleName = null;
867 // First check in active users then in local configured users
868 if (activeUsers.containsKey(username)) {
869 List<String> roles = activeUsers.get(username).getUserRoles();
870 roleName = (roles == null || roles.isEmpty())? null : roles.get(0);
871 } else if (localUserConfigList.containsKey(username)) {
872 UserConfig config = localUserConfigList.get(username);
873 roleName = (config == null)? null : config.getRole();
876 if (roleName == null) {
877 return UserLevel.NOUSER;
880 // For now only one role per user is allowed
881 if (roleName.equals(UserLevel.SYSTEMADMIN.toString())) {
882 return UserLevel.SYSTEMADMIN;
884 if (roleName.equals(UserLevel.NETWORKADMIN.toString())) {
885 return UserLevel.NETWORKADMIN;
887 if (roleName.equals(UserLevel.NETWORKOPERATOR.toString())) {
888 return UserLevel.NETWORKOPERATOR;
890 if (this.containerAuthorizationClient != null
891 && this.containerAuthorizationClient
892 .isApplicationRole(roleName)) {
893 return UserLevel.CONTAINERUSER;
895 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
896 if (client.isApplicationRole(roleName)) {
897 return UserLevel.APPUSER;
900 return UserLevel.NOUSER;
904 public Status saveConfiguration() {
905 boolean success = true;
906 Status ret = saveLocalUserList();
907 if (!ret.isSuccess()) {
910 ret = saveAAAServerList();
911 if (!ret.isSuccess()) {
914 ret = saveAuthorizationList();
915 if (!ret.isSuccess()) {
920 return new Status(StatusCode.SUCCESS, null);
923 return new Status(StatusCode.INTERNALERROR,
924 "Failed to save user configurations");
928 public UserDetails loadUserByUsername(String username)
929 throws UsernameNotFoundException {
930 AuthenticatedUser user = activeUsers.get(username);
933 boolean enabled = true;
934 boolean accountNonExpired = true;
935 boolean credentialsNonExpired = true;
936 boolean accountNonLocked = true;
938 return new User(username, localUserConfigList.get(username)
939 .getPassword(), enabled, accountNonExpired,
940 credentialsNonExpired, accountNonLocked,
941 user.getGrantedAuthorities(getUserLevel(username)));
943 throw new UsernameNotFoundException("User not found " + username);
947 public boolean supports(Class<?> authentication) {
948 return UsernamePasswordAuthenticationToken.class
949 .isAssignableFrom(authentication);
954 public SecurityContextRepository getSecurityContextRepo() {
955 return securityContextRepo;
958 public void setSecurityContextRepo(
959 SecurityContextRepository securityContextRepo) {
960 this.securityContextRepo = securityContextRepo;
964 public Authentication authenticate(Authentication authentication)
965 throws AuthenticationException {
967 if (StringUtils.isBlank((String) authentication.getCredentials())
968 || StringUtils.isBlank((String) authentication.getPrincipal())) {
969 throw new BadCredentialsException(
970 "Username or credentials did not match");
973 AuthResultEnum result = authenticate(
974 (String) authentication.getPrincipal(),
975 (String) authentication.getCredentials());
976 if (result.equals(AuthResultEnum.AUTHOR_PASS)
977 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
978 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
980 AuthenticatedUser user = activeUsers.get(authentication
981 .getPrincipal().toString());
984 throw new AuthenticationServiceException(
985 "Authentication Failure");
988 authentication = new UsernamePasswordAuthenticationToken(
989 authentication.getPrincipal(),
990 authentication.getCredentials(),
991 user.getGrantedAuthorities(getUserLevel(authentication
993 return authentication;
996 throw new BadCredentialsException(
997 "Username or credentials did not match");
1001 // following are setters for use in unit testing
1002 void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1004 this.localUserConfigList = ucl;
1008 void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1010 this.remoteServerConfigList = scl;
1014 void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1016 this.authorizationConfList = acl;
1020 void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1022 this.activeUsers = au;
1026 void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1028 this.authProviders = ap;
1033 public ISessionManager getSessionManager() {
1034 return this.sessionMgr;
1037 public void setSessionMgr(ISessionManager sessionMgr) {
1038 this.sessionMgr = sessionMgr;
1041 public String getPassword(String username) {
1042 return localUserConfigList.get(username).getPassword();