这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
写在前面
通过前几篇的原理剖析,我们这一篇来一篇很干的理论实战,那就是如何自定义用户认证,
实现自定义用户认证的过程通常涉及两大部分内容,
一方面需要使用 User 和 Authority 对象来完成定制化的用户管理
另一方面需要把这个定制化的用户管理嵌入整个用户认证流程中。下面我们分别详细分析。
实现用户管理
我们知道在 Spring Security 中,代表用户信息的就是 UserDetails 接口。我们在前几篇文章中也介绍过 UserDetails 接口的具体定义。如果你想实现自定义的用户信息,扩展这个接口即可。实现方式如下所示:
1 | java复制代码public class CustomUserDetails implements UserDetails { |
上述 CustomUserDetails 类实现了 UserDetails 接口中约定的所有需要实现的方法。请注意,这里的 getAuthorities() 方法中,我们将 User 对象中的 Authority 列表转换为了 Spring Security 中代表用户权限的SimpleGrantedAuthority 列表。
当然,所有的自定义用户信息和权限信息都是维护在数据库中的,所以为了获取这些信息,我们需要创建数据访问层组件,这个组件就是 UserRepository,定义如下:
1 | java复制代码public interface UserRepository extends JpaRepository<User, Integer> { |
这里只是简单扩展了 Spring Data JPA 中的 JpaRepository 接口,并使用方法名衍生查询机制定义了根据用户名获取用户信息的 findUserByUsername 方法。
现在,我们已经能够在数据库中维护自定义用户信息,也能够根据这些用户信息获取到 UserDetails 对象,那么接下来要做的事情就是扩展 UserDetailsService。自定义 CustomUserDetailsService 实现如下所示:
1 | java复制代码@Service |
这里我们通过 UserRepository 查询数据库来获取 CustomUserDetails 信息,如果传入的用户名没有对应的 CustomUserDetails 则会抛出异常。
实现认证流程
我们再次回顾 AuthenticationProvider 的接口定义,如下所示:
1 | java复制代码public interface AuthenticationProvider { |
实现自定义认证流程要做的也是实现 AuthenticationProvider 中的这两个方法,而认证过程势必要借助于前面介绍的 CustomUserDetailsService。
我们先来看一下 AuthenticationProvider 接口的实现类 AuthenticationProviderService,如下所示:
1 | java复制代码@Service |
1、AuthenticationProviderService 类虽然看起来比较长,但代码基本都是自解释的。我们首先通过 CustomUserDetailsService 从数据库中获取用户信息并构造成 CustomUserDetails 对象。然后,根据指定的密码加密器对用户密码进行验证。
2、如果验证通过则构建一个UsernamePasswordAuthenticationToken 对象并返回,反之直接抛出 BadCredentialsException 异常。而在 supports() 方法中指定的就是这个目标 UsernamePasswordAuthenticationToken 对象。
好了。今天就学到这里,我们下期学一下安全配置,一点一点学,每次看太多可能也消化不了,最后多说一句。欢迎大家点击我头像查看Security专栏(设计模式专栏已完结),目前正在进行的并发队列专题和Security的专题
弦外之音
感谢你的阅读,如果你感觉学到了东西,麻烦您点赞,关注。也欢迎有问题我们下面评论交流
加油! 我们下期再见!
给大家分享几个我前面写的几篇骚操作
本文转载自: 掘金