• 【Spring Security 系列】(二)剖析基础组件之认证功能


    Spring Security

    架构:https://spring.io/guides/topicals/spring-security-architecture
    文档:https://docs.spring.io/spring-security/site/docs/5.3.13.RELEASE/reference/html5/

    谈到应用安全框架就离不开两个核心功能:认证(Authentication)、授权(Authorization)。

    1. 认证
      解决 “你是谁?” 的问题。常用的认证方式就是用户登录验证。
    2. 授权
      解决 “你能干什么?” 的问题。

    认证(Authentication)

    常用的认证方式就是通过用户名和密码进行登录,
    那用户登录时,就需要获取系统中已有的用户信息进行验证,比如检查密码是否匹配、用户状态是否正常等,
    如果验证通过,那表示登录成功,则考虑返回cookie或者token,如果验证失败,那就需要返回相应的提示信息;
    有登录自然就有了登出,登出后自然需要返回相应的提示信息。

    整个流程下来,就需要不同的功能组件配合,包括:登录接口、用户信息查询、密码验证、认证成功处理、认证失败处理、登出接口、登出失败处理。

    Spring Security 对于诸多功能点都抽象为接口,以实现灵活的扩展。
    就比如用户信息查询功能,在认证的时候可能只需要用户名和密码,但框架不关注你从哪里获取到这些信息,可以从内存中,可以从数据库中等等,所以,将用户信息查询功能抽象成一个接口,方法只需要返回用户名和密码,至于实现可自由扩展。

    下面我们就开始一一说明 Spring Security 对上述的功能点是如何设计的。

    登录接口

    Spring Security设计了 UsernamePasswordAuthenticationFilter 过滤器来提供登录接口,请求路径为 POST /login,请求字段为 usernamepassword

    用户信息查询

    Spring Security设计了 UserDetailsService 接口用于获取用户信息,其接口定义如下:

    public interface UserDetailsService {
        UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
    }
    
    • 1
    • 2
    • 3

    loadUserByUsername 方法用于通过用户名获取用户信息。

    还有一个值得关注的点就是方法的返回值是 UserDetails
    UserDetails定义了在认证系统中需要的用户信息的最小子集,这些信息足以完成认证流程,而不需要关注使用者的用户表设计有多少个字段。
    就比如说,只需要用户名和密码就能做认证了,像是年龄身高体重这些和认证完全不搭边的可以不关注。实际上UserDetails没那么简单,它还设计了像过期、锁定等功能,其接口定义如下:

    public interface UserDetails extends Serializable {
        Collection<? extends GrantedAuthority> getAuthorities();
        String getPassword();
        String getUsername();
        boolean isAccountNonExpired();
        boolean isAccountNonLocked();
        boolean isCredentialsNonExpired();
        boolean isEnabled();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    密码加密与验证

    Spring Security设计了 PasswordEncoder 接口来对密码进行加密和验证,其接口定义如下:

    public interface PasswordEncoder {
        String encode(CharSequence rawPassword);
        boolean matches(CharSequence rawPassword, String encodedPassword);
    }
    
    • 1
    • 2
    • 3
    • 4

    encode 方法用于将明文密码加密成密文。一般是在存储用户密码前进行加密保存。
    matches 方法用于验证明文密码和密文是否一致。一般是用在用户登录时,验证输入的明文密码和存储的密文是否一致。

    认证成功处理器

    Spring Security设计了 AuthenticationSuccessHandler 接口来定义认证成功后的处理逻辑,其接口定义如下:

    public interface AuthenticationSuccessHandler {
        void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException;
    }
    
    • 1
    • 2
    • 3

    认证失败处理器

    Spring Security设计了 AuthenticationFailureHandler 接口来定义认证失败后的处理逻辑,其接口定义如下:

    public interface AuthenticationFailureHandler {
        void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException;
    }
    
    • 1
    • 2
    • 3

    登出接口

    Spring Security设计了 LogoutFilter 过滤器来提供登出接口,请求路径为 POST /logout

    登出成功处理器

    Spring Security设计了 LogoutSuccessHandler 接口来定义登出成功后的处理逻辑,其接口定义如下:

    public interface LogoutSuccessHandler {
        void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException;
    }
    
    • 1
    • 2
    • 3

    end

  • 相关阅读:
    AcWing 858. Prim算法求最小生成树
    嵌入式linux系统中UART子系统基本实现
    MySQL之表的增删查改(1)
    【KingbaseES】sys_dump命令详解及示例
    Linux查看文件大小的简单指令
    * 论文笔记 【OffDQ: An Offline Deep Learning Framework for QoS Prediction】
    RabbitMQ消息发送和接收(实例)
    授权控制-数据库用户分类、授权(GRANT)、收权(REVOKE)
    GPT-5 一年半后发布?对此你有何期待?
    # 用飞书来谈恋爱,飞书机器人定时给女朋友问好
  • 原文地址:https://blog.csdn.net/qq_31772441/article/details/126213773