Spring security学习笔记(一) | 青训营笔记

90 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 15 天

本节开始学习记录一款鉴权框架。每个系统几乎都会有一个权限系统,如果能用框架写的话能大大地提高开发效率,本节就学习Spring security这一款安全框架。

环境搭建

引入依赖

<!-- Spring Security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.7.3</version>

整体架构

  • 认证(Authentication)
    • AuthenticationManager
      public interface AutenticationManager {
                      Authentication authenticate(Authentication authentication) throw AuthenticationException;
      }
      
      • 认证由AuthenticationManager接口负责
        • 返回Authentication(存有用户信息)表示认证成功,抛出异常表示认证失败
        • 其主要实现类为ProvideManager,其当中管理众多AuthenticationProvider实例,每个实例表示一种认证方式
    • Authentication
      public interface Authentication extends Pricipal,Serializable {
                      Collection<? extends GranteAuthority> getAuthorities();//获取用户权限信息
                      Object getCredentials();//获取用户凭证信息
                      Object getDetails();//获取用户详细信息
                      Object getPrincipal();//获取用户身份信息,用户名、用户对象等
                      boolean isAuthenticated();//用户是否认证成功
                      void setAuthenticated(boolean isAuthenticated) throws IllegalAtgumentException;
      }
      
      • 认证以及认证成功的信息主要有Authentication 的实现类进行保存
    • SecurityContextHolder
      • SecurityContextHolder用来获取登录之后用户信息。Spring Security 会将登录用户数据保存在 Session 中。但是,为了使用方便,Spring Security在此基础上还做了一些改进,其中最主要的一个变化就是线程绑定。当用户登录成功后,Spring Security 会将登录成功的用户信息保存到 SecurityContextHolder 中。SecurityContextHolder 中的数据保存默认是通过ThreadLoca来实现的,使用 ThreadLocal创建的变量只能被当前线程访问,不能被其他线程访问和修改,也就是用户数据和请求线程绑定在一起。当登录请求处理完毕后,Spring Security 会将SecurityContextHolder 中的数据拿出来保存到 Session 中,同时将 SecurityContexHolder 中的数据清空。以后每当有请求到来时,Spring Security 就会先从 Session 中取出用户登录数据,保存到 SecurityContextHolder 中,方便在该请求的后续处理过程中使用,同时在请求结束时将 SecurityContextHolder 中的数据拿出来保存到 Session 中,然后将 SecuritySecurityContextHolder 中的数据清空。这一策略非常方便用户在 Controller、Service 层以及任何代码中获取当前登录用户数据。
      • 流程概述
        1. 收到请求,请求认证成功后生成Authentication
        2. Authentication保存到SecurityContextHolder(由本地线程ThreadLocal所绑定)
        3. 本次请求结束后,将SecurityContextHolder清空,同时将在其保存的Authentication保存到Session中去
        4. 再次请求时,依据SessionIdSession中获取Authentication,并再次保存到SecurityContextHolder,方便使用
        5. 重复步骤2-4