认证篇:Spring Security 基于表单登录的认证模式

图1-3 总结图

原理探讨

当我们在项目中引入 Spring Security的相关依赖后,默认的就是表单登录形式;俗话说:“听人劝,吃饱饭”,既然 Spring Security已经给我们安排的明明白白了,我们就从表单登录开始吧。

在开始之前,我们可以站在 Spring Security的角度上思考:如果我自己来实现表单登录的功能,那么我需要做哪些工作呢?

就我个人而言,我可能会考虑以下几点:

  • 配置用户信息,存储如账号、密码等;密码不能以明文传输,需要加密功能

  • 执行校验

  • 认证成功或者失败的处理方案

可以简单的制作成如下流程图:

图1-1 表单登录简单流程图

上方属于我们自己设想的实现方案,属于"低配版"模式,下面我们来看看 Spring Security是怎么做的。 Spring Security的思路和我们大同小异,优点在于其提供了很好的封装,提高了框架本身的可扩展性。

Spring Security的实现步骤如下:

  1. UsernamePasswordAuthenticationFilter拦截器拦截前端传递的表单登录请求,将登录信息(username、password)封装成 UsernamePasswordAuthenticationToken,传递给 AuthenticationManager认证管理器

  2. AuthenticationManager认证管理器根据Token的类型遍历获取对应的Provider,也即是 DaoAuthenticationProvider,执行认证流程

  3. DaoAuthenticationProvider依靠 PasswordEncoderUserDetailsService对登录请求进行验证

  4. 验证通过,由AuthenticationSuccessHandler认证成功处理器进行处理

  5. 验证失败,由AuthenticationFailureHandler认证失败处理器进行处理

制作成流程图如示:

图1-2 Spring Security表单登录认证流程图

这时你可能会一脸懵逼:这咋和刚刚我们自己设想的完全不一样呀~ 又是Manager又是Provider的;莫慌,且听我慢慢道来。

上面出现了很多新的概念,我们目前不需要十分细致的了解它们是怎么发挥作用的,只需要大概知道它们有什么用的即可;具体的介绍会在下篇《认证(二):表单登录认证流程源码解析》娓娓道来。

  • UsernamePasswordAuthenticationFilter表单登录拦截器,用以捕获前端传递的登录信息(username、password),并将登录信息封装成某些Token

  • AuthenticationManager认证管理器,可简单的理解为分配工作的领导。DaoAuthenticationProviderDAO认证处理器,相当于被安排干活的童鞋;从名字DAO也可以简单的推测出:它与数据库中的用户信息密不可分。

  • PasswordEncoder密码加密器,密码不能铭文传输,需要加密。UserDetailsService用户信息Service层,这个也很好理解,前端传递的登录信息肯定是有对应的数据库实体存储。

  • AuthenticationSuccessHandler认证成功处理器 AuthenticationFailureHandler认证失败处理器。

经过上述的原理探讨,我们大体上能弄懂了整个表单登录有哪几个模块需要处理;可简单的总结为3个模块:

  1. 登录前置处理: 用户信息的封装、密码加密器的设置

  2. 登录中处理: 登录的校验

  3. 登录后置处理: 登录失败、登录成功的处理方案

小试牛刀

俗话说:“光说不练假把式”,那么就让我们来实战一番吧。

登录前置处理

作为一个Java Web项目,第一步当然是引入相关依赖;直接引入Spring Boot封装好的starter即可。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
Step-1 配置用户信息

Spring Security提供了UserDetails接口,用于获取用户的基本信息(账号密码、权限集合、是否锁定等等),我们只需要根据自身的业务场景,实现该接口即可。

Spring Security提供的UserDetails.class接口

public interface UserDetails extends Serializable {
   

    /**
     * 用户权限集,默认需要添加ROLE_作为前缀
     */
    Collection<? extends GrantedAuthority> getAuthorities();

    /**
     * 获取用户密码
     */
    String getPassword();

    /**
     * UserDetails的接口
     * 获取用户名
     */
    String getUsername();

     /**
     * 账户是否未过期  --true则为未过期
     */
    boolean isAccountNonExpired();

    /**
     * 账户是否未被锁定
     */
    boolean isAccountNonLocked();

    /**
     * 账户凭证是否未过期
     */
    boolean isCredentialsNonExpired();

    /**
     * 账户是否可用
     */
    boolean isEnabled();
}

自定义业务相关的用户信息类,业务定义的UserInfo.class必须带有usernamepassword相关的信息,用于做用户验证;项目根据自身需求来判断是否需要使用下

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值