【SpringSecurity】用户自定义认证

自定义用户认证逻辑 

  • 处理用户信息获取逻辑-UserDetailsService 
用户信息被封装在一个接口里面的UserDetailsService,由SpringSecurity提供,如下: 
这里写图片描述 
这里写图片描述
该接口里面有一个loadUserByUsername方法,传入参数为userName,返回值为userDetails,作用为:根据用户在前面输入用户名,从存储系统(数据库)读取一个用户信息,这个用户信息封装在一个userDetails实现类里面,该方法处理完毕返回以后,SpringSecurity拿着这个用户信息去做一些处理和校验,处理和校验都通过了,会把这个用户信息放到session里面,认为登录成功了,如果通过userName找不到用户信息,就会抛出一个UserNameNotFoundException异常,异常拦截器会处理该异常。开发者可以自定义一个实现UserDetailsService接口的类,来个性化实现里面该接口的loadUserByUsername的方法;如下: 


@Component
public class MyUserDetailsService implements UserDetailsService {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //此处应该根据传入参数username查询数据库或其他缓存里面的是否存在该用户信息
        logger.info("登录用户名:"+username);
        logger.info("数据库密码是:"+ passwordEncoder.encode("123456"));
        //根据用户名查找用户信息
        //根据查找到的用户信息判断用户是否被冻结
        //返回的信息包括:用户认证和授权信息(如果有必要的话),用户名和密码匹配上了,就算认证成功,spring security会根据BrowserSecurityConfig配置的权限去验证这个权限
        return new User(username,passwordEncoder.encode("123456"),
                true,true,true,true,AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }
}

  • 处理用户校验逻辑-UserDetails 
userDetails这个接口封装了SpringSecurity登录的时候所需要的所有信息: 

权限信息:


密码:


用户名:


账户是否过期:


密码是否过期:


账户是否锁定(冻结)可恢复:


账户是否可用(是否被删除)不可恢复:


注意: 
1、实际使用中,我们并不一定要用SpringSecurity的userDetails类,可以用用户实体实现该userDetails的接口,然后用户是否过期是否冻结这些逻辑写到user实体类 

2、userDetails里面的Boolean方法都得返回为true才能验证通过 

  • 处理密码加密解密-PasswordEncoder 

处理加密和解密是一个新的接口,passwordEncoder,如下:


这个接口里面有两个方法: 

把密码进行加密,用户注册的时候,需要调用该方法对密码进行加密,然后存到数据库中:


下面的方法是输入密码和存储密码进行匹配,这个是SpringSecurity调用的,拿到userDetails返回值以后,会拿到里面的password,和用户在登录请求里面输入的密码进行matches匹配校验,如下:


实现该功能,可以采用BCryptPasswordEncoder实现类,也可以自定义一个实现类。 

BCryptPasswordEncoder会随机生成一个盐,生成最后的密码串的时候,把随机的盐混在这个串里面,每次判断的时候,会用每次生成的盐在反推回来当时加密的串是什么,最终来判断是否匹配,这样可以保证同样的密码可能有不一样的加密串,推荐使用该加密方式。

小结

上面只是大概的说明了一下实现思路,网上认证的demo很多,大家可以根据demo和实现思路去实践一下。

猜你喜欢

转载自blog.csdn.net/zlt995768025/article/details/80302488