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 // local authorization info for remotely authenticated users
86 private ConcurrentMap<String, AuthorizationConfig> authorizationConfList;
87 private ConcurrentMap<String, AuthenticatedUser> activeUsers;
88 private ConcurrentMap<String, IAAAProvider> authProviders;
89 private ConcurrentMap<Long, String> localUserListSaveConfigEvent,
90 remoteServerSaveConfigEvent, authorizationSaveConfigEvent;
91 private IClusterGlobalServices clusterGlobalService = null;
92 private SecurityContextRepository securityContextRepo = new UserSecurityContextRepository();
93 private IContainerAuthorization containerAuthorizationClient;
94 private Set<IResourceAuthorization> applicationAuthorizationClients;
95 private ISessionManager sessionMgr = new SessionManager();
97 public boolean addAAAProvider(IAAAProvider provider) {
98 if (provider == null || provider.getName() == null
99 || provider.getName().trim().isEmpty()) {
102 if (authProviders.get(provider.getName()) != null) {
106 authProviders.put(provider.getName(), provider);
110 public void removeAAAProvider(IAAAProvider provider) {
111 authProviders.remove(provider.getName());
114 public IAAAProvider getAAAProvider(String name) {
115 return authProviders.get(name);
119 public Set<String> getAAAProviderNames() {
120 return authProviders.keySet();
123 @SuppressWarnings("deprecation")
124 private void allocateCaches() {
125 this.applicationAuthorizationClients = Collections
126 .synchronizedSet(new HashSet<IResourceAuthorization>());
127 if (clusterGlobalService == null) {
128 logger.error("un-initialized clusterGlobalService, can't create cache");
133 clusterGlobalService.createCache("usermanager.localUserConfigList",
134 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
136 clusterGlobalService.createCache(
137 "usermanager.remoteServerConfigList",
138 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
140 clusterGlobalService.createCache(
141 "usermanager.authorizationConfList",
142 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
144 clusterGlobalService.createCache("usermanager.activeUsers",
145 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
147 clusterGlobalService.createCache(
148 "usermanager.localUserSaveConfigEvent",
149 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
151 clusterGlobalService.createCache(
152 "usermanager.remoteServerSaveConfigEvent",
153 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
155 clusterGlobalService.createCache(
156 "usermanager.authorizationSaveConfigEvent",
157 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
158 } catch (CacheConfigException cce) {
159 logger.error("\nCache configuration invalid - check cache mode");
160 } catch (CacheExistException ce) {
161 logger.error("\nCache already exits - destroy and recreate if needed");
165 @SuppressWarnings({ "unchecked", "deprecation" })
166 private void retrieveCaches() {
167 if (clusterGlobalService == null) {
168 logger.error("un-initialized clusterService, can't retrieve cache");
172 activeUsers = (ConcurrentMap<String, AuthenticatedUser>) clusterGlobalService
173 .getCache("usermanager.activeUsers");
174 if (activeUsers == null) {
175 logger.error("\nFailed to get cache for activeUsers");
178 localUserConfigList = (ConcurrentMap<String, UserConfig>) clusterGlobalService
179 .getCache("usermanager.localUserConfigList");
180 if (localUserConfigList == null) {
181 logger.error("\nFailed to get cache for localUserConfigList");
184 remoteServerConfigList = (ConcurrentMap<String, ServerConfig>) clusterGlobalService
185 .getCache("usermanager.remoteServerConfigList");
186 if (remoteServerConfigList == null) {
187 logger.error("\nFailed to get cache for remoteServerConfigList");
190 authorizationConfList = (ConcurrentMap<String, AuthorizationConfig>) clusterGlobalService
191 .getCache("usermanager.authorizationConfList");
192 if (authorizationConfList == null) {
193 logger.error("\nFailed to get cache for authorizationConfList");
196 localUserListSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
197 .getCache("usermanager.localUserSaveConfigEvent");
198 if (localUserListSaveConfigEvent == null) {
199 logger.error("\nFailed to get cache for localUserSaveConfigEvent");
202 remoteServerSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
203 .getCache("usermanager.remoteServerSaveConfigEvent");
204 if (remoteServerSaveConfigEvent == null) {
205 logger.error("\nFailed to get cache for remoteServerSaveConfigEvent");
208 authorizationSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
209 .getCache("usermanager.authorizationSaveConfigEvent");
210 if (authorizationSaveConfigEvent == null) {
211 logger.error("\nFailed to get cache for authorizationSaveConfigEvent");
215 private void loadConfigurations() {
216 // To encode and decode user and server configuration objects
220 * Do not load local startup file if we already got the configurations
221 * synced from another cluster node
223 if (localUserConfigList.isEmpty()) {
226 if (remoteServerConfigList.isEmpty()) {
229 if (authorizationConfList.isEmpty()) {
234 private void loadSecurityKeys() {
238 private void checkDefaultNetworkAdmin() {
239 // If startup config is not there, it's old or it was deleted,
240 // need to add Default Admin
241 if (!localUserConfigList.containsKey(defaultAdmin)) {
242 List<String> roles = new ArrayList<String>(1);
243 roles.add(defaultAdminRole);
244 localUserConfigList.put(defaultAdmin, new UserConfig(defaultAdmin,
245 defaultAdminPassword, roles));
250 public AuthResultEnum authenticate(String userName, String password) {
251 IAAAProvider aaaClient;
252 AuthResponse rcResponse = null;
253 AuthenticatedUser result;
254 boolean remotelyAuthenticated = false;
255 boolean authorizationInfoIsPresent = false;
256 boolean authorized = false;
259 * Attempt remote authentication first if server is configured
261 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
262 String protocol = aaaServer.getProtocol();
263 aaaClient = this.getAAAProvider(protocol);
264 if (aaaClient != null) {
265 rcResponse = aaaClient.authService(userName, password,
266 aaaServer.getAddress(), aaaServer.getSecret());
267 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
269 "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
270 userName, aaaServer.getAddress());
271 remotelyAuthenticated = true;
273 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
275 "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
276 new Object[] { userName, aaaServer.getAddress(),
277 rcResponse.getStatus().toString() });
280 "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
281 new Object[] { userName, aaaServer.getAddress(),
282 rcResponse.getStatus().toString() });
287 if (!remotelyAuthenticated) {
288 UserConfig localUser = this.localUserConfigList.get(userName);
289 if (localUser == null) {
291 "Local Authentication Failed for User:\"{}\", Reason: "
292 + "user not found in Local Database", userName);
293 return (AuthResultEnum.AUTH_INVALID_LOC_USER);
295 rcResponse = localUser.authenticate(password);
296 if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
298 "Local Authentication Failed for User: \"{}\", Reason: {}",
299 userName, rcResponse.getStatus().toString());
301 return (rcResponse.getStatus());
303 logger.info("Local Authentication Succeeded for User: \"{}\"",
308 * Authentication succeeded
310 result = new AuthenticatedUser(userName);
313 * Extract attributes from response All the information we are
314 * interested in is in the first Cisco VSA (vendor specific attribute).
315 * Just process the first VSA and return
317 String attributes = (rcResponse.getData() != null && !rcResponse
318 .getData().isEmpty()) ? rcResponse.getData().get(0) : null;
321 * Check if the authorization information is present
323 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
326 * The AAA server was only used to perform the authentication Look for
327 * locally stored authorization info for this user If found, add the
328 * data to the rcResponse
330 if (remotelyAuthenticated && !authorizationInfoIsPresent) {
332 "No Remote Authorization Info provided by Server for User: \"{}\"",
335 "Looking for Local Authorization Info for User: \"{}\"",
338 AuthorizationConfig resource = authorizationConfList.get(userName);
339 if (resource != null) {
340 logger.info("Found Local Authorization Info for User: \"{}\"",
342 attributes = resource.getRolesString();
345 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
349 * Common response parsing for local & remote authenticated user Looking
350 * for authorized resources, detecting attributes' validity
352 if (authorizationInfoIsPresent) {
353 // Identifying the administrative role
354 result.setRoleList(attributes.split(" "));
357 logger.info("Not able to find Authorization Info for User: \"{}\"",
362 * Add profile for authenticated user
364 putUserInActiveList(userName, result);
366 logger.info("User \"{}\" authorized for the following role(s): {}",
367 userName, result.getUserRoles());
369 logger.info("User \"{}\" Not Authorized for any role ", userName);
372 return rcResponse.getStatus();
375 // Check in the attributes string whether or not authorization information
377 private boolean checkAuthorizationInfo(String attributes) {
378 return (attributes != null && !attributes.isEmpty());
381 private void putUserInActiveList(String user, AuthenticatedUser result) {
382 activeUsers.put(user, result);
385 private void removeUserFromActiveList(String user) {
386 if (!activeUsers.containsKey(user)) {
387 // as cookie persists in cache, we can get logout for unexisting
391 activeUsers.remove(user);
395 public Status saveLocalUserList() {
396 // Publish the save config event to the cluster nodes
397 localUserListSaveConfigEvent.put(new Date().getTime(), SAVE);
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 // Publish the save config event to the cluster nodes
410 remoteServerSaveConfigEvent.put(new Date().getTime(), SAVE);
411 return saveAAAServerListInternal();
414 private Status saveAAAServerListInternal() {
415 ObjectWriter objWriter = new ObjectWriter();
416 return objWriter.write(new ConcurrentHashMap<String, ServerConfig>(
417 remoteServerConfigList), serversFileName);
421 public Status saveAuthorizationList() {
422 // Publish the save config event to the cluster nodes
423 authorizationSaveConfigEvent.put(new Date().getTime(), SAVE);
424 return saveAuthorizationListInternal();
427 private Status saveAuthorizationListInternal() {
428 ObjectWriter objWriter = new ObjectWriter();
429 return objWriter.write(
430 new ConcurrentHashMap<String, AuthorizationConfig>(
431 authorizationConfList), authFileName);
435 public Object readObject(ObjectInputStream ois)
436 throws FileNotFoundException, IOException, ClassNotFoundException {
437 // Perform the class deserialization locally, from inside the package
438 // where the class is defined
439 return ois.readObject();
442 @SuppressWarnings("unchecked")
443 private void loadUserConfig() {
444 ObjectReader objReader = new ObjectReader();
445 ConcurrentMap<String, UserConfig> confList = (ConcurrentMap<String, UserConfig>) objReader
446 .read(this, usersFileName);
448 if (confList == null) {
452 for (UserConfig conf : confList.values()) {
457 @SuppressWarnings("unchecked")
458 private void loadServerConfig() {
459 ObjectReader objReader = new ObjectReader();
460 ConcurrentMap<String, ServerConfig> confList = (ConcurrentMap<String, ServerConfig>) objReader
461 .read(this, serversFileName);
463 if (confList == null) {
467 for (ServerConfig conf : confList.values()) {
472 @SuppressWarnings("unchecked")
473 private void loadAuthConfig() {
474 ObjectReader objReader = new ObjectReader();
475 ConcurrentMap<String, AuthorizationConfig> confList = (ConcurrentMap<String, AuthorizationConfig>) objReader
476 .read(this, authFileName);
478 if (confList == null) {
482 for (AuthorizationConfig conf : confList.values()) {
488 * Interaction with GUI START
490 public Status addRemoveLocalUser(UserConfig AAAconf, boolean delete) {
491 // UserConfig Validation check
492 Status validCheck = AAAconf.validate();
493 if (!validCheck.isSuccess()) {
497 // Update Config database
499 if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
500 String msg = "Invalid Request: Default Network Admin User "
501 + "cannot be deleted";
503 return new Status(StatusCode.NOTALLOWED, msg);
505 localUserConfigList.remove(AAAconf.getUser());
507 * A user account has been removed form local database, we assume
508 * admin does not want this user to stay connected, in case he has
509 * an open session. So we clean the active list as well.
511 removeUserFromActiveList(AAAconf.getUser());
513 if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
514 String msg = "Invalid Request: Default Network Admin User "
517 return new Status(StatusCode.NOTALLOWED, msg);
519 localUserConfigList.put(AAAconf.getUser(), AAAconf);
522 return new Status(StatusCode.SUCCESS, null);
525 private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
527 if (!AAAconf.isValid()) {
528 String msg = "Invalid Server configuration";
530 return new Status(StatusCode.BADREQUEST, msg);
533 // Update configuration database
535 remoteServerConfigList.remove(AAAconf.getAddress());
537 remoteServerConfigList.put(AAAconf.getAddress(), AAAconf);
540 return new Status(StatusCode.SUCCESS, null);
543 private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
544 Status configCheck = AAAconf.validate();
545 if (!configCheck.isSuccess()) {
546 String msg = "Invalid Authorization configuration: "
547 + configCheck.getDescription();
549 return new Status(StatusCode.BADREQUEST, msg);
552 // Update configuration database
554 authorizationConfList.remove(AAAconf.getUser());
556 authorizationConfList.put(AAAconf.getUser(), AAAconf);
559 return new Status(StatusCode.SUCCESS, null);
563 public Status addLocalUser(UserConfig AAAconf) {
564 return addRemoveLocalUser(AAAconf, false);
568 public Status removeLocalUser(UserConfig AAAconf) {
569 return addRemoveLocalUser(AAAconf, true);
573 public Status removeLocalUser(String userName) {
574 if (userName == null || userName.trim().isEmpty()) {
575 return new Status(StatusCode.BADREQUEST, "Invalid user name");
577 if (!localUserConfigList.containsKey(userName)) {
578 return new Status(StatusCode.NOTFOUND, "User does not exist");
580 return addRemoveLocalUser(localUserConfigList.get(userName), true);
584 public Status addAAAServer(ServerConfig AAAconf) {
585 return addRemoveAAAServer(AAAconf, false);
589 public Status removeAAAServer(ServerConfig AAAconf) {
590 return addRemoveAAAServer(AAAconf, true);
594 public Status addAuthInfo(AuthorizationConfig AAAconf) {
595 return addRemoveAuthInfo(AAAconf, false);
599 public Status removeAuthInfo(AuthorizationConfig AAAconf) {
600 return addRemoveAuthInfo(AAAconf, true);
604 public List<UserConfig> getLocalUserList() {
605 return new ArrayList<UserConfig>(localUserConfigList.values());
609 public List<ServerConfig> getAAAServerList() {
610 return new ArrayList<ServerConfig>(remoteServerConfigList.values());
614 public List<AuthorizationConfig> getAuthorizationList() {
615 return new ArrayList<AuthorizationConfig>(
616 authorizationConfList.values());
620 public Status changeLocalUserPassword(String user, String curPassword,
621 String newPassword) {
622 UserConfig targetConfigEntry = null;
624 // update configuration entry
625 targetConfigEntry = localUserConfigList.get(user);
626 if (targetConfigEntry == null) {
627 return new Status(StatusCode.NOTFOUND, "User not found");
629 Status status = targetConfigEntry
630 .update(curPassword, newPassword, null);
631 if (!status.isSuccess()) {
634 // Trigger cluster update
635 localUserConfigList.put(user, targetConfigEntry);
637 logger.info("Password changed for User \"{}\"", user);
643 public void userLogout(String userName) {
644 // TODO: if user was authenticated through AAA server, send
645 // Acct-Status-Type=stop message to server with logout as reason
646 removeUserFromActiveList(userName);
647 logger.info("User \"{}\" logged out", userName);
651 * This function will get called by http session mgr when session times out
654 public void userTimedOut(String userName) {
655 // TODO: if user was authenticated through AAA server, send
656 // Acct-Status-Type=stop message to server with timeout as reason
657 removeUserFromActiveList(userName);
658 logger.info("User \"{}\" timed out", userName);
662 public String getAccessDate(String user) {
663 return this.activeUsers.get(user).getAccessDate();
667 public synchronized Map<String, List<String>> getUserLoggedIn() {
668 Map<String, List<String>> loggedInList = new HashMap<String, List<String>>();
669 for (Map.Entry<String, AuthenticatedUser> user : activeUsers.entrySet()) {
670 String userNameShow = user.getKey();
671 loggedInList.put(userNameShow, user.getValue().getUserRoles());
677 * Interaction with GUI END
681 * Cluster notifications
685 public void entryCreated(Long key, String cacheName, boolean originLocal) {
686 // don't react on this event
690 public void entryUpdated(Long key, String new_value, String cacheName,
691 boolean originLocal) {
692 if (cacheName.equals("localUserSaveConfigEvent")) {
693 this.saveLocalUserListInternal();
694 } else if (cacheName.equals("remoteServerSaveConfigEvent")) {
695 this.saveAAAServerListInternal();
696 } else if (cacheName.equals("authorizationSaveConfigEvent")) {
697 this.saveAuthorizationListInternal();
702 public void entryDeleted(Long key, String cacheName, boolean originLocal) {
703 // don't react on this event
706 public void _umAddUser(CommandInterpreter ci) {
707 String userName = ci.nextArgument();
708 String password = ci.nextArgument();
709 String role = ci.nextArgument();
711 List<String> roles = new ArrayList<String>();
712 while (role != null) {
713 if (!role.trim().isEmpty()) {
716 role = ci.nextArgument();
719 if (userName == null || userName.trim().isEmpty() || password == null
720 || password.trim().isEmpty() || roles == null
721 || roles.isEmpty()) {
722 ci.println("Invalid Arguments");
723 ci.println("umAddUser <user_name> <password> <user_role>");
726 ci.print(this.addLocalUser(new UserConfig(userName, password, roles)));
729 public void _umRemUser(CommandInterpreter ci) {
730 String userName = ci.nextArgument();
732 if (userName == null || userName.trim().isEmpty()) {
733 ci.println("Invalid Arguments");
734 ci.println("umRemUser <user_name>");
737 UserConfig target = localUserConfigList.get(userName);
738 if (target == null) {
739 ci.println("User not found");
742 ci.println(this.removeLocalUser(target));
745 public void _umGetUsers(CommandInterpreter ci) {
746 for (UserConfig conf : this.getLocalUserList()) {
747 ci.println(conf.getUser() + " " + conf.getRoles());
751 public void _addAAAServer(CommandInterpreter ci) {
752 String server = ci.nextArgument();
753 String secret = ci.nextArgument();
754 String protocol = ci.nextArgument();
756 if (server == null || secret == null || protocol == null) {
757 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
760 ServerConfig s = new ServerConfig(server, secret, protocol);
764 public void _removeAAAServer(CommandInterpreter ci) {
765 String server = ci.nextArgument();
766 String secret = ci.nextArgument();
767 String protocol = ci.nextArgument();
769 if (server == null || secret == null || protocol == null) {
770 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
773 ServerConfig s = new ServerConfig(server, secret, protocol);
777 public void _printAAAServers(CommandInterpreter ci) {
778 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
779 ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
784 public String getHelp() {
785 StringBuffer help = new StringBuffer();
786 return help.toString();
789 void setClusterGlobalService(IClusterGlobalServices s) {
790 logger.debug("Cluster Service Global set");
791 this.clusterGlobalService = s;
794 void unsetClusterGlobalService(IClusterGlobalServices s) {
795 if (this.clusterGlobalService == s) {
796 logger.debug("Cluster Service Global removed!");
797 this.clusterGlobalService = null;
801 void unsetContainerAuthClient(IContainerAuthorization s) {
802 if (this.containerAuthorizationClient == s) {
803 this.containerAuthorizationClient = null;
807 void setContainerAuthClient(IContainerAuthorization s) {
808 this.containerAuthorizationClient = s;
811 void setAppAuthClient(IResourceAuthorization s) {
812 this.applicationAuthorizationClients.add(s);
815 void unsetAppAuthClient(IResourceAuthorization s) {
816 this.applicationAuthorizationClients.remove(s);
820 * Function called by the dependency manager when all the required
821 * dependencies are satisfied
828 * Function called by the dependency manager when at least one dependency
829 * become unsatisfied or when the component is shutting down because for
830 * example bundle is being stopped.
837 * Function called by dependency manager after "init ()" is called and after
838 * the services provided by the class are registered in the service registry
842 authProviders = new ConcurrentHashMap<String, IAAAProvider>();
843 // Instantiate cluster synced variables
847 // Read startup configuration and populate databases
848 loadConfigurations();
850 // Make sure default Network Admin account is there
851 checkDefaultNetworkAdmin();
852 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
854 bundleContext.registerService(CommandProvider.class.getName(), this,
859 * Function called by the dependency manager before the services exported by
860 * the component are unregistered, this will be followed by a "destroy ()"
868 public List<String> getUserRoles(String userName) {
869 if (userName == null) {
870 return new ArrayList<String>(0);
872 AuthenticatedUser locatedUser = activeUsers.get(userName);
873 return (locatedUser == null) ? new ArrayList<String>(0) : locatedUser
878 public UserLevel getUserLevel(String username) {
879 // Returns the controller well-know user level for the passed user
880 List<String> rolesNames = null;
882 // First check in active users then in local configured users
883 if (activeUsers.containsKey(username)) {
884 List<String> roles = activeUsers.get(username).getUserRoles();
885 rolesNames = (roles == null || roles.isEmpty()) ? null : roles;
886 } else if (localUserConfigList.containsKey(username)) {
887 UserConfig config = localUserConfigList.get(username);
888 rolesNames = (config == null) ? null : config.getRoles();
891 if (rolesNames == null) {
892 return UserLevel.NOUSER;
895 // Check against the well known controller roles first
896 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
897 return UserLevel.SYSTEMADMIN;
899 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
900 return UserLevel.NETWORKADMIN;
902 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
903 return UserLevel.NETWORKOPERATOR;
905 // Check if container user now
906 if (containerAuthorizationClient != null) {
907 for (String roleName : rolesNames) {
908 if (containerAuthorizationClient.isApplicationRole(roleName)) {
909 return UserLevel.CONTAINERUSER;
913 // Finally check if application user
914 if (applicationAuthorizationClients != null) {
915 for (String roleName : rolesNames) {
916 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
917 if (client.isApplicationRole(roleName)) {
918 return UserLevel.APPUSER;
923 return UserLevel.NOUSER;
928 public List<UserLevel> getUserLevels(String username) {
929 // Returns the controller well-know user levels for the passed user
930 List<String> rolesNames = null;
931 List<UserLevel> levels = new ArrayList<UserLevel>();
933 if (activeUsers.containsKey(username)) {
934 List<String> roles = activeUsers.get(username).getUserRoles();
935 rolesNames = (roles == null || roles.isEmpty()) ? null : roles;
936 } else if (localUserConfigList.containsKey(username)) {
937 UserConfig config = localUserConfigList.get(username);
938 rolesNames = (config == null) ? null : config.getRoles();
941 if (rolesNames == null) {
945 // Check against the well known controller roles first
946 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
947 levels.add(UserLevel.SYSTEMADMIN);
949 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
950 levels.add(UserLevel.NETWORKADMIN);
952 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
953 levels.add(UserLevel.NETWORKOPERATOR);
955 // Check if container user now
956 if (containerAuthorizationClient != null) {
957 for (String roleName : rolesNames) {
958 if (containerAuthorizationClient.isApplicationRole(roleName)) {
959 levels.add(UserLevel.CONTAINERUSER);
964 // Finally check if application user
965 if (applicationAuthorizationClients != null) {
966 for (String roleName : rolesNames) {
967 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
968 if (client.isApplicationRole(roleName)) {
969 levels.add(UserLevel.APPUSER);
979 public Status saveConfiguration() {
980 boolean success = true;
981 Status ret = saveLocalUserList();
982 if (!ret.isSuccess()) {
985 ret = saveAAAServerList();
986 if (!ret.isSuccess()) {
989 ret = saveAuthorizationList();
990 if (!ret.isSuccess()) {
995 return new Status(StatusCode.SUCCESS, null);
998 return new Status(StatusCode.INTERNALERROR,
999 "Failed to save user configurations");
1003 public UserDetails loadUserByUsername(String username)
1004 throws UsernameNotFoundException {
1005 AuthenticatedUser user = activeUsers.get(username);
1008 boolean enabled = true;
1009 boolean accountNonExpired = true;
1010 boolean credentialsNonExpired = true;
1011 boolean accountNonLocked = true;
1013 return new User(username, localUserConfigList.get(username)
1014 .getPassword(), enabled, accountNonExpired,
1015 credentialsNonExpired, accountNonLocked,
1016 user.getGrantedAuthorities(getUserLevel(username)));
1018 throw new UsernameNotFoundException("User not found " + username);
1023 public boolean supports(Class<?> authentication) {
1024 return UsernamePasswordAuthenticationToken.class
1025 .isAssignableFrom(authentication);
1030 public SecurityContextRepository getSecurityContextRepo() {
1031 return securityContextRepo;
1034 public void setSecurityContextRepo(
1035 SecurityContextRepository securityContextRepo) {
1036 this.securityContextRepo = securityContextRepo;
1040 public Authentication authenticate(Authentication authentication)
1041 throws AuthenticationException {
1043 if (StringUtils.isBlank((String) authentication.getCredentials())
1044 || StringUtils.isBlank((String) authentication.getPrincipal())) {
1045 throw new BadCredentialsException(
1046 "Username or credentials did not match");
1049 AuthResultEnum result = authenticate(
1050 (String) authentication.getPrincipal(),
1051 (String) authentication.getCredentials());
1052 if (result.equals(AuthResultEnum.AUTHOR_PASS)
1053 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
1054 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
1056 AuthenticatedUser user = activeUsers.get(authentication
1057 .getPrincipal().toString());
1060 throw new AuthenticationServiceException(
1061 "Authentication Failure");
1064 authentication = new UsernamePasswordAuthenticationToken(
1065 authentication.getPrincipal(),
1066 authentication.getCredentials(),
1067 user.getGrantedAuthorities(getUserLevel(authentication
1069 return authentication;
1072 throw new BadCredentialsException(
1073 "Username or credentials did not match");
1078 // following are setters for use in unit testing
1079 void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1081 this.localUserConfigList = ucl;
1085 void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1087 this.remoteServerConfigList = scl;
1091 void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1093 this.authorizationConfList = acl;
1097 void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1099 this.activeUsers = au;
1103 void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1105 this.authProviders = ap;
1110 public ISessionManager getSessionManager() {
1111 return this.sessionMgr;
1114 public void setSessionMgr(ISessionManager sessionMgr) {
1115 this.sessionMgr = sessionMgr;
1119 public String getPassword(String username) {
1120 return localUserConfigList.get(username).getPassword();