SpringSecurity自定义用户认证
实现自定义认证过程必须实现spring security
提供的UserDetailsService
,该接口只用一个抽象方法loadUserByUsername
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
它返回的Userdetails
对象也是一个接口,包含一些用于描述用户信息的方法
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
isAccountNonExpired
:用于判断账户是否未过期
isAccountNonLocked
:方法用于判断账户是否未锁定
isCredentialsNonExpired
:用于判断用户凭证是否没过期,即密码是否未过期
isEnabled
:方法用于判断用户是否可用
在实际开发中,我们可以直接使用spring security提供的UserDetails
的实现类org.springframework.security.core.userdetails.User
,也可以自己实现UserDetails
接口,拓展一些其他用户信息
这里我直接实现UserDetails
接口,用于模拟数据(一般从数据库中取数据)
public class MyUser implements UserDetails {
private String username;
private String password;
//判断账户是否过期
private boolean accountNonExpired = true;
//账户是否锁定
private boolean accountNonLocked= true;
//于判断用户凭证是否没过期,即密码是否未过期
private boolean credentialsNonExpired= true;
//判断用户是否可用
private boolean enabled= true;
//getter和setter方法
}
然后实现UserDetailsService
接口
因为spring security
密码默认是加密的,所以现在启动类注入一个PasswordEncoder
对象
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
PasswordEncoder
是一个密码加密的接口,而BCryptPasswordEncoder
是它的一个实现类,它每次加密后的结果都不一样
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
//模拟一个用户
MyUser user = new MyUser();
//密码加密
user.setPassword(passwordEncoder.encode("root"));
user.setUsername("root");
System.out.println(user.getPassword());
return new User(user.getUsername(),user.getPassword(),user.isEnabled(),user.isAccountNonExpired(),user.isCredentialsNonExpired(),user.isAccountNonLocked(), AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
这里使用的是七个参数的构造方法,参数含义在前面已经解释过了,最后一个参数是用户权限,如果为空会出现InternalAuthenticationServiceException
异常,所以在这里使用AuthorityUtils.commaSeparatedStringToAuthorityList()
方法模拟一个admin
权限,该方法可以将逗号分隔的字符串转换为权限集合。
此外还有一个三个参数的构造方法
public User(String username, String password, Collection<? extends GrantedAuthority> authorities) {
this(username, password, true, true, true, true, authorities);
}
可以看到,它内部实现就是调用了七个参数的构造方法,authorities
参数是一个集合,里面的元素必须继承GrantedAuthority
。
整合thymeleaf实现自定义登录页面:https://blog.csdn.net/xj_524256192/article/details/105772552