用户管理
UserDetails : 用户在 spring security 中的描述 。比如一个用户的姓名,密码等等
UserDetailsService: 用户在 spring security 中行为的描述,比如如何通过用户名找到用户,用户是否已经认证等等
GrantedAuthority: 允许用户是否可以执行一些定义好的行为
UserDetailsManager: 拓展自 UserDetailsService,多了一些额外的行为,比如增删改查用户信息等等。
架构
在具体的用户管理中,其代码关系如下所示:
从架构图可以得知 UserDetailsService 使用 UserDetails. 所以第一步就需要我们根据 spring-security 里面对 UserDetails 的定义进行自己的实现。
用户管理
UserDetails
先看一下 spring security 是如何描述 UserDetails 的:
UserDetails 跟 User 类比较相近,但是为了以后更好的维护,需要将这两个类分开创建。
创建 CustomUserDetails 类 ```java @Component public class CustomerUserDetails implements UserDetails { @Autowired User user;
public CustomerUserDetails(User user){
this.user = user;
}
public final User getUser() {
return user;}
@Override public Collection<? extends GrantedAuthority> getAuthorities() {
return null;}
@Override public String getPassword() {
return this.user.getPassword();}
@Override public String getUsername() {
return this.user.getUsername();}
@Override public boolean isAccountNonExpired() {
return false;}
@Override public boolean isAccountNonLocked() {
return false;}
@Override public boolean isCredentialsNonExpired() {
return false;}
@Override public boolean isEnabled() {
return true;} }
<a name="5uc8M"></a>
## UserDetailsService
创建完 UserDetails 以后,我们需要定义其行为。
2. 创建 CustomUserDetailsService 类
```java
@Component
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.selectByName(username);
if (user == null) {
throw new UsernameNotFoundException("No found");
}
return new CustomerUserDetails(user);
}
}
UserDetailsService 类只有一个关键的方法,就是 loadUSerByName; 用来寻找用户是否存在。当然,这样远远不够,因为我们也没有认证,因此,我们需要实现 CustomAuthenticationProvider 类来进行密码的验证
AuthenticationProvider
创建认证类 ```java @Component public class CustomAuthenticationProvider implements AuthenticationProvider { @Autowired CustomUserDetailsService userDetailsService; @Autowired PasswordEncoder passwordEncoder; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName(); String password = String.valueOf(authentication.getCredentials()); UserDetails userDetails = userDetailsService.loadUserByUsername(username); if (passwordEncoder.matches(password,userDetails.getPassword())){ return new UsernamePasswordAuthenticationToken( userDetails.getUsername(), userDetails.getPassword(), null ); }else{ throw new BadCredentialsException("Bad Credentials"); }}
@Override public boolean supports(Class<?> aClass) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass);}
4. 最后集成到配置文件里面
```java
@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = {"com.example"})
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
CustomAuthenticationProvider customAuthenticationProvider;
@Bean
public PasswordEncoder getDelegatingPasswordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}
}
