ch01~ch08都是基于Spring Security默认的功能建立了用户、权限、分组等认证必要元素,这些基本满足用户认证的需求,并且为我们预留了很多用于自定义和扩展的接口。
Spring Security定义了用户、权限和分组的java和数据结构,这些数据结构往往与遗留的数据库不一致,但是Spring Security并未强加限制,而是可以与自定义的数据结构与数据库相适应。
详细看过前面几章的朋友应该已经知道如何去做了,那就是实现自定义的UserDetailsService提供自定义用户信息获取服务,扩张UserDetails实现自定义用户结构。
如果不需要扩展UserDetails而是只是适应遗留系统的数据库,那么可以直接配置UserDetailsService的查询语句适应Spring Security的数据结构即可.
修改WebSecurityConfigurerAdapter
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.usersByUsernameQuery("...")//配置UserDetails查询语句
.authoritiesByUsernameQuery("...")//配置用户直接Authorities查询语句
.groupAuthoritiesByUsername("...")//配置用户所属组Authorities查询语句
.passwordEncoder(passwordEncoder())//启用密码加密功能
.dataSource(dataSource);
}
如果需要扩展用户属性,比如增加电子邮件、手机后等,那么Spring Security的UserDetails的默认实现已经不能满足要求,那么就需要实现自定义UserDetails。
UserDetails是一个接口,用户可以按需实现自定义的用户对象。
UserDetails已经扩展了,默认提供的UserDetailsService已经不能满足要求,用户可以实现UserDetailsService,也可以继承JdbcUserDetailsManager,重写以下方法:
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
/**
* Create a new user with the supplied details.
*/
void createUser(UserDetails user);
/**
* Update the specified user.
*/
void updateUser(UserDetails user);
/**
* Remove the user with the given login name from the system.
*/
void deleteUser(String username);
/**
* Modify the current user's password. This should change the user's password in the
* persistent user repository (datbase, LDAP etc).
*
* @param oldPassword current password (for re-authentication if required)
* @param newPassword the password to change to
*/
void changePassword(String oldPassword, String newPassword);
/**
* Check if a user with the supplied login name exists in the system.
*/
boolean userExists(String username);
// ~ GroupManager implementation //
public List<String> findAllGroups() ;
public List<String> findUsersInGroup(String groupName);
public void createGroup(final String groupName, final List<GrantedAuthority> authorities) ;
public void deleteGroup(String groupName) ;
public void addUserToGroup(final String username, final String groupName) ;
public void removeUserFromGroup(final String username, final String groupName) ;
public List<GrantedAuthority> findGroupAuthorities(String groupName) ;
public void removeGroupAuthority(String groupName, final GrantedAuthority authority) ;
public void addGroupAuthority(final String groupName, final GrantedAuthority authority) ;
配置UserDetailsService
修改WebSecurityConfigurerAdapter
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService())//配置自定义UserDetails
.and().jdbcAuthentication()
.passwordEncoder(passwordEncoder())//启用密码加密功能
.dataSource(dataSource);
}
/**
* 自定义UserDetailsService,并发布为Spring Bean
*
* @return
*/
@Bean
public UserDetailsService userDetailsService() {
UserDetailsService userDetailsService = username -> null;
return userDetailsService;
}
以上简单配置就可以完成自定义用户、自定义用户信息获取服务于Spring Security的整合,具体信息可以查看JdbcUserDetailsService的doc
代码示例:https://github.com/wexgundam/spring.security/tree/master/ch09