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("Cache configuration invalid - check cache mode");
160 } catch (CacheExistException ce) {
161 logger.debug("Skipping cache creation as already present");
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("Failed to get cache for activeUsers");
178 localUserConfigList = (ConcurrentMap<String, UserConfig>) clusterGlobalService
179 .getCache("usermanager.localUserConfigList");
180 if (localUserConfigList == null) {
181 logger.error("Failed to get cache for localUserConfigList");
184 remoteServerConfigList = (ConcurrentMap<String, ServerConfig>) clusterGlobalService
185 .getCache("usermanager.remoteServerConfigList");
186 if (remoteServerConfigList == null) {
187 logger.error("Failed to get cache for remoteServerConfigList");
190 authorizationConfList = (ConcurrentMap<String, AuthorizationConfig>) clusterGlobalService
191 .getCache("usermanager.authorizationConfList");
192 if (authorizationConfList == null) {
193 logger.error("Failed to get cache for authorizationConfList");
196 localUserListSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
197 .getCache("usermanager.localUserSaveConfigEvent");
198 if (localUserListSaveConfigEvent == null) {
199 logger.error("Failed to get cache for localUserSaveConfigEvent");
202 remoteServerSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
203 .getCache("usermanager.remoteServerSaveConfigEvent");
204 if (remoteServerSaveConfigEvent == null) {
205 logger.error("Failed to get cache for remoteServerSaveConfigEvent");
208 authorizationSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
209 .getCache("usermanager.authorizationSaveConfigEvent");
210 if (authorizationSaveConfigEvent == null) {
211 logger.error("Failed 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 List<String> roles = null;
870 if (userName != null) {
872 * First look in active users then in local configured users,
873 * finally in local authorized users
875 if (activeUsers.containsKey(userName)) {
876 roles = activeUsers.get(userName).getUserRoles();
877 } else if (localUserConfigList.containsKey(userName)) {
878 roles = localUserConfigList.get(userName).getRoles();
879 } else if (authorizationConfList.containsKey(userName)) {
880 roles = authorizationConfList.get(userName).getRoles();
883 return (roles == null) ? new ArrayList<String>(0) : roles;
887 public UserLevel getUserLevel(String username) {
888 // Returns the highest controller user level for the passed user
889 List<String> rolesNames = getUserRoles(username);
891 if (rolesNames.isEmpty()) {
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 user levels for the passed user
930 List<String> rolesNames = getUserRoles(username);
931 List<UserLevel> levels = new ArrayList<UserLevel>();
933 if (rolesNames.isEmpty()) {
937 // Check against the well known controller roles first
938 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
939 levels.add(UserLevel.SYSTEMADMIN);
941 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
942 levels.add(UserLevel.NETWORKADMIN);
944 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
945 levels.add(UserLevel.NETWORKOPERATOR);
947 // Check if container user now
948 if (containerAuthorizationClient != null) {
949 for (String roleName : rolesNames) {
950 if (containerAuthorizationClient.isApplicationRole(roleName)) {
951 levels.add(UserLevel.CONTAINERUSER);
956 // Finally check if application user
957 if (applicationAuthorizationClients != null) {
958 for (String roleName : rolesNames) {
959 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
960 if (client.isApplicationRole(roleName)) {
961 levels.add(UserLevel.APPUSER);
971 public Status saveConfiguration() {
972 boolean success = true;
973 Status ret = saveLocalUserList();
974 if (!ret.isSuccess()) {
977 ret = saveAAAServerList();
978 if (!ret.isSuccess()) {
981 ret = saveAuthorizationList();
982 if (!ret.isSuccess()) {
987 return new Status(StatusCode.SUCCESS, null);
990 return new Status(StatusCode.INTERNALERROR,
991 "Failed to save user configurations");
995 public UserDetails loadUserByUsername(String username)
996 throws UsernameNotFoundException {
997 AuthenticatedUser user = activeUsers.get(username);
1000 boolean enabled = true;
1001 boolean accountNonExpired = true;
1002 boolean credentialsNonExpired = true;
1003 boolean accountNonLocked = true;
1005 return new User(username, localUserConfigList.get(username)
1006 .getPassword(), enabled, accountNonExpired,
1007 credentialsNonExpired, accountNonLocked,
1008 user.getGrantedAuthorities(getUserLevel(username)));
1010 throw new UsernameNotFoundException("User not found " + username);
1015 public boolean supports(Class<?> authentication) {
1016 return UsernamePasswordAuthenticationToken.class
1017 .isAssignableFrom(authentication);
1022 public SecurityContextRepository getSecurityContextRepo() {
1023 return securityContextRepo;
1026 public void setSecurityContextRepo(
1027 SecurityContextRepository securityContextRepo) {
1028 this.securityContextRepo = securityContextRepo;
1032 public Authentication authenticate(Authentication authentication)
1033 throws AuthenticationException {
1035 if (StringUtils.isBlank((String) authentication.getCredentials())
1036 || StringUtils.isBlank((String) authentication.getPrincipal())) {
1037 throw new BadCredentialsException(
1038 "Username or credentials did not match");
1041 AuthResultEnum result = authenticate(
1042 (String) authentication.getPrincipal(),
1043 (String) authentication.getCredentials());
1044 if (result.equals(AuthResultEnum.AUTHOR_PASS)
1045 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
1046 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
1048 AuthenticatedUser user = activeUsers.get(authentication
1049 .getPrincipal().toString());
1052 throw new AuthenticationServiceException(
1053 "Authentication Failure");
1056 authentication = new UsernamePasswordAuthenticationToken(
1057 authentication.getPrincipal(),
1058 authentication.getCredentials(),
1059 user.getGrantedAuthorities(getUserLevel(authentication
1061 return authentication;
1064 throw new BadCredentialsException(
1065 "Username or credentials did not match");
1070 // Following are setters for use in unit testing
1071 void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1073 this.localUserConfigList = ucl;
1077 void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1079 this.remoteServerConfigList = scl;
1083 void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1085 this.authorizationConfList = acl;
1089 void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1091 this.activeUsers = au;
1095 void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1097 this.authProviders = ap;
1102 public ISessionManager getSessionManager() {
1103 return this.sessionMgr;
1106 public void setSessionMgr(ISessionManager sessionMgr) {
1107 this.sessionMgr = sessionMgr;
1111 public String getPassword(String username) {
1112 return localUserConfigList.get(username).getPassword();
1116 public boolean isRoleInUse(String role) {
1117 if (role == null || role.isEmpty()) {
1120 // Check against controller roles
1121 if (role.equals(UserLevel.SYSTEMADMIN.toString())
1122 || role.equals(UserLevel.NETWORKADMIN.toString())
1123 || role.equals(UserLevel.NETWORKOPERATOR.toString())) {
1126 // Check if container roles
1127 if (containerAuthorizationClient != null) {
1128 if (containerAuthorizationClient.isApplicationRole(role)) {
1132 // Finally if application role
1133 if (applicationAuthorizationClients != null) {
1134 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
1135 if (client.isApplicationRole(role)) {