向Spring安全上下文中存储的主体对象添加其他详细信息

我正在使用Spring 3.0和Spring Security 3.我能够使用Spring Security对数据库进行身份validation。 使用:

SecurityContextHolder.getContext().getAuthentication().getPrincipal() 

我能够检索当前登录用户的用户名。 我希望添加其他详细信息,例如用户标识和模块访问存储在Spring Security上下文中的主体对象,以便我以后可以检索它。 如何向主体对象添加其他详细信息,然后如何在jsp或java类中检索它。 如果可能,请提供适当的代码段。

编辑:我使用JDBC访问我的数据库。

提前致谢。

为了向经过身份validation的用户添加更多详细信息。 您需要首先创建自己的User对象实现,该实现应该扩展Spring安全性User对象。 之后,您可以添加要添加到经过身份validation的用户的属性。 完成此操作后,您需要在UserDetailService中返回用户对象的实现(如果您没有使用LDAP进行身份validation)。 此链接提供了向经过身份validation的用户添加更多详细信息的详细信息 –

http://javahotpot.blogspot.in/2013/12/spring-security-adding-more-information.html

(我假设您有一个基本的Spring Security配置,并且知道基本组件如何协同工作)

最“正确”的方法是提供自己的AuthenticationProvider实现,返回自定义Authentication实现。 然后,您可以使用所需的一切填写此Authentication实例。 例如:

 public class MyAuthentication extends UsernamePasswordAuthenticationToken implements Authentication { public MyAuthentication(Object principal, Object credentials, int moduleCode) { super(principal, credentials); this.moduleCode = moduleCode; } public MyAuthentication(Object principal, Object credentials, Collection authorities,int moduleCode) { super(principal, credentials, authorities); this.moduleCode = moduleCode; } private int moduleCode; public getModuleCode() { return moduleCode; } } public class MyAuthenticationProvider extends DaoAuthenticationProvider { private Collection obtainAuthorities(UserDetails user) { // return granted authorities for user, according to your requirements } private int obtainModuleCode(UserDetails user) { // return moduleCode for user, according to your requirements } @Override public Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) { // Suppose this user implementation has a moduleCode property MyAuthentication result = new MyAuthentication(authentication.getPrincipal(), authentication.getCredentials(), obtainAuthorities(user), obtainModuleCode(user)); result.setDetails(authentication.getDetails()); return result; } } 

然后,在applicationContext.xml

     ...  

我想你可以通过提供AuthenticationDetailsAuthenticationDetailsSource自定义实现来实现它,但我认为这将是一个不太干净的方法。

这是你需要的:

  1. 扩展spring Userorg.springframework.security.core.userdetails.User )类以及您需要的属性。
  2. 扩展spring UserDetailsServiceorg.springframework.security.core.userdetails.UserDetailsService )并填充上面的对象。 覆盖loadUserByUsername并返回扩展用户类
  3. AuthenticationManagerBuilder设置自定义UserDetailsService

例如

 public class CurrentUser extends User{ //This constructor is a must public CurrentUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection authorities) { super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); } //Setter and getters are required private String firstName; private String lastName; } 

Custom userdetails可以是:

 @Service("userDetailsService") public class CustomUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException { //Try to find user and its roles, for example here we try to get it from database via a DAO object //Do not confuse this foo.bar.User with CurrentUser or spring User, this is a temporary object which holds user info stored in database foo.bar.User user = userDao.findByUserName(username); //Build user Authority. some how a convert from your custom roles which are in database to spring GrantedAuthority List authorities = buildUserAuthority(user.getUserRole()); //The magic is happen in this private method ! return buildUserForAuthentication(user, authorities); } //Fill your extended User object (CurrentUser) here and return it private User buildUserForAuthentication(foo.bar.User user, List authorities) { String username = user.getUsername(); String password = user.getPassword(); boolean enabled = true; boolean accountNonExpired = true; boolean credentialsNonExpired = true; boolean accountNonLocked = true; return new CurrentUser(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); //If your database has more information of user for example firstname,... You can fill it here //CurrentUser currentUser = new CurrentUser(....) //currentUser.setFirstName( user.getfirstName() ); //..... //return currentUser ; } private List buildUserAuthority(Set userRoles) { Set setAuths = new HashSet(); // Build user's authorities for (UserRole userRole : userRoles) { setAuths.add(new SimpleGrantedAuthority(userRole.getRole())); } return new ArrayList(setAuths); } } 

配置spring安全上下文

 @Configuration @EnableWebSecurity @PropertySource("classpath://configs.properties") public class SecurityContextConfig extends WebSecurityConfigurerAdapter { @Autowired @Qualifier("userDetailsService") private UserDetailsService userDetailsService; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } 

一切都完成了!

您可以调用(CurrentUser)getAuthentication().getPrincipal()来获取新的CurrentUser或设置一些属性。

您需要做的“唯一”事情是创建自己的UserDetailsS​​ervice实现,该实现返回您自己的UserDetails对象实现。

请参阅此处获取实现基于JPA的UserDetailsService的教程。