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);
118 public Set<String> getAAAProviderNames() {
119 return authProviders.keySet();
122 @SuppressWarnings("deprecation")
123 private void allocateCaches() {
124 this.applicationAuthorizationClients = Collections
125 .synchronizedSet(new HashSet<IResourceAuthorization>());
126 if (clusterGlobalService == null) {
127 logger.error("un-initialized clusterGlobalService, can't create cache");
132 clusterGlobalService.createCache("usermanager.localUserConfigList",
133 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
135 clusterGlobalService.createCache(
136 "usermanager.remoteServerConfigList",
137 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
139 clusterGlobalService.createCache(
140 "usermanager.authorizationConfList",
141 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
143 clusterGlobalService.createCache("usermanager.activeUsers",
144 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
146 clusterGlobalService.createCache(
147 "usermanager.localUserSaveConfigEvent",
148 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
150 clusterGlobalService.createCache(
151 "usermanager.remoteServerSaveConfigEvent",
152 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
154 clusterGlobalService.createCache(
155 "usermanager.authorizationSaveConfigEvent",
156 EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
157 } catch (CacheConfigException cce) {
158 logger.error("\nCache configuration invalid - check cache mode");
159 } catch (CacheExistException ce) {
160 logger.error("\nCache already exits - destroy and recreate if needed");
164 @SuppressWarnings({ "unchecked", "deprecation" })
165 private void retrieveCaches() {
166 if (clusterGlobalService == null) {
167 logger.error("un-initialized clusterService, can't retrieve cache");
171 activeUsers = (ConcurrentMap<String, AuthenticatedUser>) clusterGlobalService
172 .getCache("usermanager.activeUsers");
173 if (activeUsers == null) {
174 logger.error("\nFailed to get cache for activeUsers");
177 localUserConfigList = (ConcurrentMap<String, UserConfig>) clusterGlobalService
178 .getCache("usermanager.localUserConfigList");
179 if (localUserConfigList == null) {
180 logger.error("\nFailed to get cache for localUserConfigList");
183 remoteServerConfigList = (ConcurrentMap<String, ServerConfig>) clusterGlobalService
184 .getCache("usermanager.remoteServerConfigList");
185 if (remoteServerConfigList == null) {
186 logger.error("\nFailed to get cache for remoteServerConfigList");
189 authorizationConfList = (ConcurrentMap<String, AuthorizationConfig>) clusterGlobalService
190 .getCache("usermanager.authorizationConfList");
191 if (authorizationConfList == null) {
192 logger.error("\nFailed to get cache for authorizationConfList");
195 localUserListSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
196 .getCache("usermanager.localUserSaveConfigEvent");
197 if (localUserListSaveConfigEvent == null) {
198 logger.error("\nFailed to get cache for localUserSaveConfigEvent");
201 remoteServerSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
202 .getCache("usermanager.remoteServerSaveConfigEvent");
203 if (remoteServerSaveConfigEvent == null) {
204 logger.error("\nFailed to get cache for remoteServerSaveConfigEvent");
207 authorizationSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
208 .getCache("usermanager.authorizationSaveConfigEvent");
209 if (authorizationSaveConfigEvent == null) {
210 logger.error("\nFailed to get cache for authorizationSaveConfigEvent");
214 private void loadConfigurations() {
215 // To encode and decode user and server configuration objects
219 * Do not load local startup file if we already got the configurations
220 * synced from another cluster node
222 if (localUserConfigList.isEmpty()) {
225 if (remoteServerConfigList.isEmpty()) {
228 if (authorizationConfList.isEmpty()) {
233 private void loadSecurityKeys() {
237 private void checkDefaultNetworkAdmin() {
238 // If startup config is not there, it's old or it was deleted,
239 // need to add Default Admin
240 if (!localUserConfigList.containsKey(defaultAdmin)) {
241 List<String> roles = new ArrayList<String>(1);
242 roles.add(defaultAdminRole);
243 localUserConfigList.put(defaultAdmin, new UserConfig(defaultAdmin,
244 defaultAdminPassword, roles));
249 public AuthResultEnum authenticate(String userName, String password) {
250 IAAAProvider aaaClient;
251 AuthResponse rcResponse = null;
252 AuthenticatedUser result;
253 boolean remotelyAuthenticated = false;
254 boolean authorizationInfoIsPresent = false;
255 boolean authorized = false;
258 * Attempt remote authentication first if server is configured
260 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
261 String protocol = aaaServer.getProtocol();
262 aaaClient = this.getAAAProvider(protocol);
263 if (aaaClient != null) {
264 rcResponse = aaaClient.authService(userName, password,
265 aaaServer.getAddress(), aaaServer.getSecret());
266 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
268 "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
269 userName, aaaServer.getAddress());
270 remotelyAuthenticated = true;
272 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
274 "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
275 new Object[] {userName, aaaServer.getAddress(),
276 rcResponse.getStatus().toString()});
279 "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
280 new Object[] {userName, aaaServer.getAddress(),
281 rcResponse.getStatus().toString()});
286 if (!remotelyAuthenticated) {
287 UserConfig localUser = this.localUserConfigList.get(userName);
288 if (localUser == null) {
290 "Local Authentication Failed for User:\"{}\", Reason: "
291 + "user not found in Local Database", userName);
292 return (AuthResultEnum.AUTH_INVALID_LOC_USER);
294 rcResponse = localUser.authenticate(password);
295 if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
297 "Local Authentication Failed for User: \"{}\", Reason: {}",
298 userName, rcResponse.getStatus().toString());
300 return (rcResponse.getStatus());
302 logger.info("Local Authentication Succeeded for User: \"{}\"",
307 * Authentication succeeded
309 result = new AuthenticatedUser(userName);
312 * Extract attributes from response All the information we are
313 * interested in is in the first Cisco VSA (vendor specific attribute).
314 * Just process the first VSA and return
316 String attributes = (rcResponse.getData() != null && !rcResponse
317 .getData().isEmpty()) ? rcResponse.getData().get(0) : null;
320 * Check if the authorization information is present
322 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
325 * The AAA server was only used to perform the authentication Look for
326 * locally stored authorization info for this user If found, add the
327 * data to the rcResponse
329 if (remotelyAuthenticated && !authorizationInfoIsPresent) {
331 "No Remote Authorization Info provided by Server for User: \"{}\"",
334 "Looking for Local Authorization Info for User: \"{}\"",
337 AuthorizationConfig resource = authorizationConfList.get(userName);
338 if (resource != null) {
339 logger.info("Found Local Authorization Info for User: \"{}\"",
341 attributes = resource.getRolesString();
344 authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
348 * Common response parsing for local & remote authenticated user Looking
349 * for authorized resources, detecting attributes' validity
351 if (authorizationInfoIsPresent) {
352 // Identifying the administrative role
353 result.setRoleList(attributes.split(" "));
356 logger.info("Not able to find Authorization Info for User: \"{}\"",
361 * Add profile for authenticated user
363 putUserInActiveList(userName, result);
365 logger.info("User \"{}\" authorized for the following role(s): {}",
366 userName, result.getUserRoles());
368 logger.info("User \"{}\" Not Authorized for any role ", userName);
371 return rcResponse.getStatus();
374 // Check in the attributes string whether or not authorization information
376 private boolean checkAuthorizationInfo(String attributes) {
377 return (attributes != null && !attributes.isEmpty());
380 private void putUserInActiveList(String user, AuthenticatedUser result) {
381 activeUsers.put(user, result);
384 private void removeUserFromActiveList(String user) {
385 if (!activeUsers.containsKey(user)) {
386 // as cookie persists in cache, we can get logout for unexisting
390 activeUsers.remove(user);
393 public Status saveLocalUserList() {
394 // Publish the save config event to the cluster nodes
395 localUserListSaveConfigEvent.put(new Date().getTime(), SAVE);
396 return saveLocalUserListInternal();
399 private Status saveLocalUserListInternal() {
400 ObjectWriter objWriter = new ObjectWriter();
401 return objWriter.write(new ConcurrentHashMap<String, UserConfig>(
402 localUserConfigList), usersFileName);
405 public Status saveAAAServerList() {
406 // Publish the save config event to the cluster nodes
407 remoteServerSaveConfigEvent.put(new Date().getTime(), SAVE);
408 return saveAAAServerListInternal();
411 private Status saveAAAServerListInternal() {
412 ObjectWriter objWriter = new ObjectWriter();
413 return objWriter.write(new ConcurrentHashMap<String, ServerConfig>(
414 remoteServerConfigList), serversFileName);
417 public Status saveAuthorizationList() {
418 // Publish the save config event to the cluster nodes
419 authorizationSaveConfigEvent.put(new Date().getTime(), SAVE);
420 return saveAuthorizationListInternal();
423 private Status saveAuthorizationListInternal() {
424 ObjectWriter objWriter = new ObjectWriter();
425 return objWriter.write(
426 new ConcurrentHashMap<String, AuthorizationConfig>(
427 authorizationConfList), authFileName);
431 public Object readObject(ObjectInputStream ois)
432 throws FileNotFoundException, IOException, ClassNotFoundException {
433 // Perform the class deserialization locally, from inside the package
434 // where the class is defined
435 return ois.readObject();
438 @SuppressWarnings("unchecked")
439 private void loadUserConfig() {
440 ObjectReader objReader = new ObjectReader();
441 ConcurrentMap<String, UserConfig> confList = (ConcurrentMap<String, UserConfig>) objReader
442 .read(this, usersFileName);
444 if (confList == null) {
448 for (UserConfig conf : confList.values()) {
453 @SuppressWarnings("unchecked")
454 private void loadServerConfig() {
455 ObjectReader objReader = new ObjectReader();
456 ConcurrentMap<String, ServerConfig> confList = (ConcurrentMap<String, ServerConfig>) objReader
457 .read(this, serversFileName);
459 if (confList == null) {
463 for (ServerConfig conf : confList.values()) {
468 @SuppressWarnings("unchecked")
469 private void loadAuthConfig() {
470 ObjectReader objReader = new ObjectReader();
471 ConcurrentMap<String, AuthorizationConfig> confList = (ConcurrentMap<String, AuthorizationConfig>) objReader
472 .read(this, authFileName);
474 if (confList == null) {
478 for (AuthorizationConfig conf : confList.values()) {
484 * Interaction with GUI START
486 public Status addRemoveLocalUser(UserConfig AAAconf, boolean delete) {
487 // UserConfig Validation check
488 Status validCheck = AAAconf.validate();
489 if (!validCheck.isSuccess()) {
493 // Update Config database
495 if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
496 String msg = "Invalid Request: Default Network Admin User "
497 + "cannot be deleted";
499 return new Status(StatusCode.NOTALLOWED, msg);
501 localUserConfigList.remove(AAAconf.getUser());
503 * A user account has been removed form local database, we assume
504 * admin does not want this user to stay connected, in case he has
505 * an open session. So we clean the active list as well.
507 removeUserFromActiveList(AAAconf.getUser());
509 if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
510 String msg = "Invalid Request: Default Network Admin User "
513 return new Status(StatusCode.NOTALLOWED, msg);
515 localUserConfigList.put(AAAconf.getUser(), AAAconf);
518 return new Status(StatusCode.SUCCESS, null);
521 private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
523 if (!AAAconf.isValid()) {
524 String msg = "Invalid Server configuration";
526 return new Status(StatusCode.BADREQUEST, msg);
529 // Update configuration database
531 remoteServerConfigList.remove(AAAconf.getAddress());
533 remoteServerConfigList.put(AAAconf.getAddress(), AAAconf);
536 return new Status(StatusCode.SUCCESS, null);
539 private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
540 Status configCheck = AAAconf.validate();
541 if (!configCheck.isSuccess()) {
542 String msg = "Invalid Authorization configuration: "
543 + configCheck.getDescription();
545 return new Status(StatusCode.BADREQUEST, msg);
548 // Update configuration database
550 authorizationConfList.remove(AAAconf.getUser());
552 authorizationConfList.put(AAAconf.getUser(), AAAconf);
555 return new Status(StatusCode.SUCCESS, null);
559 public Status addLocalUser(UserConfig AAAconf) {
560 return addRemoveLocalUser(AAAconf, false);
564 public Status removeLocalUser(UserConfig AAAconf) {
565 return addRemoveLocalUser(AAAconf, true);
569 public Status removeLocalUser(String userName) {
570 if (userName == null || userName.trim().isEmpty()) {
571 return new Status(StatusCode.BADREQUEST, "Invalid user name");
573 if (!localUserConfigList.containsKey(userName)) {
574 return new Status(StatusCode.NOTFOUND, "User does not exist");
576 return addRemoveLocalUser(localUserConfigList.get(userName), true);
580 public Status addAAAServer(ServerConfig AAAconf) {
581 return addRemoveAAAServer(AAAconf, false);
585 public Status removeAAAServer(ServerConfig AAAconf) {
586 return addRemoveAAAServer(AAAconf, true);
590 public Status addAuthInfo(AuthorizationConfig AAAconf) {
591 return addRemoveAuthInfo(AAAconf, false);
595 public Status removeAuthInfo(AuthorizationConfig AAAconf) {
596 return addRemoveAuthInfo(AAAconf, true);
600 public List<UserConfig> getLocalUserList() {
601 return new ArrayList<UserConfig>(localUserConfigList.values());
605 public List<ServerConfig> getAAAServerList() {
606 return new ArrayList<ServerConfig>(remoteServerConfigList.values());
610 public List<AuthorizationConfig> getAuthorizationList() {
611 return new ArrayList<AuthorizationConfig>(
612 authorizationConfList.values());
616 public Status changeLocalUserPassword(String user, String curPassword,
617 String newPassword) {
618 UserConfig targetConfigEntry = null;
620 // update configuration entry
621 targetConfigEntry = localUserConfigList.get(user);
622 if (targetConfigEntry == null) {
623 return new Status(StatusCode.NOTFOUND, "User not found");
625 Status status = targetConfigEntry
626 .update(curPassword, newPassword, null);
627 if (!status.isSuccess()) {
630 // Trigger cluster update
631 localUserConfigList.put(user, targetConfigEntry);
633 logger.info("Password changed for User \"{}\"", user);
639 public void userLogout(String userName) {
640 // TODO: if user was authenticated through AAA server, send
641 // Acct-Status-Type=stop message to server with logout as reason
642 removeUserFromActiveList(userName);
643 logger.info("User \"{}\" logged out", userName);
647 * This function will get called by http session mgr when session times out
650 public void userTimedOut(String userName) {
651 // TODO: if user was authenticated through AAA server, send
652 // Acct-Status-Type=stop message to server with timeout as reason
653 removeUserFromActiveList(userName);
654 logger.info("User \"{}\" timed out", userName);
658 public String getAccessDate(String user) {
659 return this.activeUsers.get(user).getAccessDate();
663 public synchronized Map<String, List<String>> getUserLoggedIn() {
664 Map<String, List<String>> loggedInList = new HashMap<String, List<String>>();
665 for (Map.Entry<String, AuthenticatedUser> user : activeUsers.entrySet()) {
666 String userNameShow = user.getKey();
667 loggedInList.put(userNameShow, user.getValue().getUserRoles());
673 * Interaction with GUI END
677 * Cluster notifications
681 public void entryCreated(Long key, String cacheName, boolean originLocal) {
682 // don't react on this event
686 public void entryUpdated(Long key, String new_value, String cacheName,
687 boolean originLocal) {
688 if (cacheName.equals("localUserSaveConfigEvent")) {
689 this.saveLocalUserListInternal();
690 } else if (cacheName.equals("remoteServerSaveConfigEvent")) {
691 this.saveAAAServerListInternal();
692 } else if (cacheName.equals("authorizationSaveConfigEvent")) {
693 this.saveAuthorizationListInternal();
698 public void entryDeleted(Long key, String cacheName, boolean originLocal) {
699 // don't react on this event
702 public void _umAddUser(CommandInterpreter ci) {
703 String userName = ci.nextArgument();
704 String password = ci.nextArgument();
705 String role = ci.nextArgument();
707 List<String> roles = new ArrayList<String>();
708 while (role != null) {
709 if (!role.trim().isEmpty()) {
712 role = ci.nextArgument();
715 if (userName == null || userName.trim().isEmpty() || password == null
716 || password.trim().isEmpty() || roles == null
717 || roles.isEmpty()) {
718 ci.println("Invalid Arguments");
719 ci.println("umAddUser <user_name> <password> <user_role>");
722 ci.print(this.addLocalUser(new UserConfig(userName, password, roles)));
725 public void _umRemUser(CommandInterpreter ci) {
726 String userName = ci.nextArgument();
728 if (userName == null || userName.trim().isEmpty()) {
729 ci.println("Invalid Arguments");
730 ci.println("umRemUser <user_name>");
733 UserConfig target = localUserConfigList.get(userName);
734 if (target == null) {
735 ci.println("User not found");
738 ci.println(this.removeLocalUser(target));
741 public void _umGetUsers(CommandInterpreter ci) {
742 for (UserConfig conf : this.getLocalUserList()) {
743 ci.println(conf.getUser() + " " + conf.getRoles());
747 public void _addAAAServer(CommandInterpreter ci) {
748 String server = ci.nextArgument();
749 String secret = ci.nextArgument();
750 String protocol = ci.nextArgument();
752 if (server == null || secret == null || protocol == null) {
753 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
756 ServerConfig s = new ServerConfig(server, secret, protocol);
760 public void _removeAAAServer(CommandInterpreter ci) {
761 String server = ci.nextArgument();
762 String secret = ci.nextArgument();
763 String protocol = ci.nextArgument();
765 if (server == null || secret == null || protocol == null) {
766 ci.println("Usage : addAAAServer <server> <secret> <protocol>");
769 ServerConfig s = new ServerConfig(server, secret, protocol);
773 public void _printAAAServers(CommandInterpreter ci) {
774 for (ServerConfig aaaServer : remoteServerConfigList.values()) {
775 ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
780 public String getHelp() {
781 StringBuffer help = new StringBuffer();
782 return help.toString();
785 void setClusterGlobalService(IClusterGlobalServices s) {
786 logger.debug("Cluster Service Global set");
787 this.clusterGlobalService = s;
790 void unsetClusterGlobalService(IClusterGlobalServices s) {
791 if (this.clusterGlobalService == s) {
792 logger.debug("Cluster Service Global removed!");
793 this.clusterGlobalService = null;
797 void unsetContainerAuthClient(IContainerAuthorization s) {
798 if (this.containerAuthorizationClient == s) {
799 this.containerAuthorizationClient = null;
803 void setContainerAuthClient(IContainerAuthorization s) {
804 this.containerAuthorizationClient = s;
807 void setAppAuthClient(IResourceAuthorization s) {
808 this.applicationAuthorizationClients.add(s);
811 void unsetAppAuthClient(IResourceAuthorization s) {
812 this.applicationAuthorizationClients.remove(s);
816 * Function called by the dependency manager when all the required
817 * dependencies are satisfied
824 * Function called by the dependency manager when at least one dependency
825 * become unsatisfied or when the component is shutting down because for
826 * example bundle is being stopped.
833 * Function called by dependency manager after "init ()" is called and after
834 * the services provided by the class are registered in the service registry
838 authProviders = new ConcurrentHashMap<String, IAAAProvider>();
839 // Instantiate cluster synced variables
843 // Read startup configuration and populate databases
844 loadConfigurations();
846 // Make sure default Network Admin account is there
847 checkDefaultNetworkAdmin();
848 BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
850 bundleContext.registerService(CommandProvider.class.getName(), this,
855 * Function called by the dependency manager before the services exported by
856 * the component are unregistered, this will be followed by a "destroy ()"
864 public List<String> getUserRoles(String userName) {
865 if (userName == null) {
866 return new ArrayList<String>(0);
868 AuthenticatedUser locatedUser = activeUsers.get(userName);
869 return (locatedUser == null) ? new ArrayList<String>(0) : locatedUser
874 public UserLevel getUserLevel(String username) {
875 // Returns the controller well-know user level for the passed user
876 List<String> rolesNames = null;
878 // First check in active users then in local configured users
879 if (activeUsers.containsKey(username)) {
880 List<String> roles = activeUsers.get(username).getUserRoles();
881 rolesNames = (roles == null || roles.isEmpty()) ? null : roles;
882 } else if (localUserConfigList.containsKey(username)) {
883 UserConfig config = localUserConfigList.get(username);
884 rolesNames = (config == null) ? null : config.getRoles();
887 if (rolesNames == null) {
888 return UserLevel.NOUSER;
891 // Check against the well known controller roles first
892 if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
893 return UserLevel.SYSTEMADMIN;
895 if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
896 return UserLevel.NETWORKADMIN;
898 if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
899 return UserLevel.NETWORKOPERATOR;
901 // Check if container user now
902 if (containerAuthorizationClient != null) {
903 for (String roleName : rolesNames) {
904 if (containerAuthorizationClient.isApplicationRole(roleName)) {
905 return UserLevel.CONTAINERUSER;
909 // Finally check if application user
910 if (applicationAuthorizationClients != null) {
911 for (String roleName : rolesNames) {
912 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
913 if (client.isApplicationRole(roleName)) {
914 return UserLevel.APPUSER;
919 return UserLevel.NOUSER;
923 public Status saveConfiguration() {
924 boolean success = true;
925 Status ret = saveLocalUserList();
926 if (!ret.isSuccess()) {
929 ret = saveAAAServerList();
930 if (!ret.isSuccess()) {
933 ret = saveAuthorizationList();
934 if (!ret.isSuccess()) {
939 return new Status(StatusCode.SUCCESS, null);
942 return new Status(StatusCode.INTERNALERROR,
943 "Failed to save user configurations");
947 public UserDetails loadUserByUsername(String username)
948 throws UsernameNotFoundException {
949 AuthenticatedUser user = activeUsers.get(username);
952 boolean enabled = true;
953 boolean accountNonExpired = true;
954 boolean credentialsNonExpired = true;
955 boolean accountNonLocked = true;
957 return new User(username, localUserConfigList.get(username)
958 .getPassword(), enabled, accountNonExpired,
959 credentialsNonExpired, accountNonLocked,
960 user.getGrantedAuthorities(getUserLevel(username)));
962 throw new UsernameNotFoundException("User not found " + username);
966 public boolean supports(Class<?> authentication) {
967 return UsernamePasswordAuthenticationToken.class
968 .isAssignableFrom(authentication);
973 public SecurityContextRepository getSecurityContextRepo() {
974 return securityContextRepo;
977 public void setSecurityContextRepo(
978 SecurityContextRepository securityContextRepo) {
979 this.securityContextRepo = securityContextRepo;
983 public Authentication authenticate(Authentication authentication)
984 throws AuthenticationException {
986 if (StringUtils.isBlank((String) authentication.getCredentials())
987 || StringUtils.isBlank((String) authentication.getPrincipal())) {
988 throw new BadCredentialsException(
989 "Username or credentials did not match");
992 AuthResultEnum result = authenticate(
993 (String) authentication.getPrincipal(),
994 (String) authentication.getCredentials());
995 if (result.equals(AuthResultEnum.AUTHOR_PASS)
996 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
997 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
999 AuthenticatedUser user = activeUsers.get(authentication
1000 .getPrincipal().toString());
1003 throw new AuthenticationServiceException(
1004 "Authentication Failure");
1007 authentication = new UsernamePasswordAuthenticationToken(
1008 authentication.getPrincipal(),
1009 authentication.getCredentials(),
1010 user.getGrantedAuthorities(getUserLevel(authentication
1012 return authentication;
1015 throw new BadCredentialsException(
1016 "Username or credentials did not match");
1020 // following are setters for use in unit testing
1021 void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1023 this.localUserConfigList = ucl;
1027 void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1029 this.remoteServerConfigList = scl;
1033 void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1035 this.authorizationConfList = acl;
1039 void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1041 this.activeUsers = au;
1045 void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1047 this.authProviders = ap;
1052 public ISessionManager getSessionManager() {
1053 return this.sessionMgr;
1056 public void setSessionMgr(ISessionManager sessionMgr) {
1057 this.sessionMgr = sessionMgr;
1060 public String getPassword(String username) {
1061 return localUserConfigList.get(username).getPassword();