一.导学

自定义用户认证逻辑

  • 处理用户信息获取逻辑
  • 处理用户校验逻辑
  • 处理密码加密解密
二.处理用户信息获取逻辑
  • 用户信息获取逻辑在Spring security中是封装在接口 UserDetailsService里面的
  • 这个接口中只有一个方法
  • 根据用户前面输入的用户名到你的存储(不管是数据库还是什么去读取一个用户信息) 用户信息封装在UserDetails接口对象中的实现类中,登陆成功会把它放到session中

Spring Authorization Server 自定义授权模式 springsecurity自定义用户认证_其他

  • 所以自定义实现这个接口来处理用户信息获取逻辑
@Component
public class MyUserDetailsService implements UserDetailsService {

    private Logger logger = LoggerFactory.getLogger(getClass());
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        logger.info("登陆用户名:"+username);
   return new User(username,“123456”,AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));//User是Spring security中对UserDetails接口的实现类 赋予一个admin权限
    }
}
  • 这样是登陆不上去的
    Spring Authorization Server 自定义授权模式 springsecurity自定义用户认证_加密解密_02
  • 这个异常是spring security5+后密码策略变更了。必须使用 PasswordEncoder 方式也就是你存储密码的时候 。后边会介绍到
三.处理用户校验逻辑

用户校验逻辑主要包括两个方面

  • 密码是否匹配(Spring security来做的 你只需要做从数据库中读取的密码是什么就可以了)
  • 其他校验(这个用户是否被冻结了 密码过期之类的)
  • 看下UserDetails的方法
    Spring Authorization Server 自定义授权模式 springsecurity自定义用户认证_用户信息_03
    这四个方法就是实现校验逻辑的,分明意思是
  • 你的账户没有过期
  • 你的账户是不是被锁定了(一般表示这个账户是否被冻结了)
  • 你的密码是否过期了
  • 你的账户是否可用(一般表示你这个用户是否被删了)【标志位而已 假删除】

冻结用户一般可以恢复 删除用户是不能恢复的

  • 所以我们来测试下
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        logger.info("登陆用户名:"+username);
        return new User(username,"123456",
                true,true,true,false,
                AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));//UserDetails实现类 处理用户校验逻辑
    }

Spring Authorization Server 自定义授权模式 springsecurity自定义用户认证_User_04

  • 在你的实现中不一定非要用spring的实现类User 你可以自己写一个逻辑 实现UserDetails接口就行
四.处理密码加密解密
  • 项目中不会直接把明文存到数据库中 从数据库中取出的东西不是一个直接的东西(123456)
  • Spring Security中是由接口PasswordEncoder控制
    Spring Authorization Server 自定义授权模式 springsecurity自定义用户认证_用户信息_05
    早期是下边的 现在选择上面的了
    Spring Authorization Server 自定义授权模式 springsecurity自定义用户认证_Spring Security_06
    只有两个方法,前者是加密,后者是加密密码和你传过来的代码是否匹配,后者是Spring security自己调用的
@Bean
    public PasswordEncoder passwordEncoder(){//处理密码加密解密
        return new BCryptPasswordEncoder();
    }
@Component
public class MyUserDetailsService implements UserDetailsService {

    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private PasswordEncoder passwordEncoder;//处理用户加密解密
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        logger.info("登陆用户名:"+username);
        String password = passwordEncoder.encode("123456");
        logger.info("登陆密码:"+password);
        return new User(username,password,
                true,true,true,true,
                AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));//UserDetails实现类 处理用户校验逻辑
    }
}

Spring Authorization Server 自定义授权模式 springsecurity自定义用户认证_加密解密_07

  • 登陆两次发现登陆密码打印并不一样,发现每次加密都不一样,这也是Spring Security的强大之处

总结

  • 处理用户信息获取逻辑 使用 UserDetailsService
  • 处理用户校验逻辑 使用 UserDetails
  • 处理密码加密解密 使用 PasswordEncoder