阶段一:SpringSecurity 项目安全基石

一、Spring Security 6:

Spring Security官方文档

Spring Cloud Security官方文档

Web项目开发中,安全是重中之重,SpringSecurity作为Spring生态官方安全框架,核心解决三大问题:

  • 认证:验证用户身份(比如账号密码是否正确),决定“谁能进入系统”;
  • 授权:控制用户可访问的资源(比如普通用户不能访问管理员页面),决定“进入系统后能做什么”;
  • 攻击防护:自带主流Web攻击防护机制,避免系统被恶意攻击。

1、典型Web安全漏洞:

(1)、XSS跨站脚本:

1、核心原理:

系统未对用户输入的内容做HTML 特殊字符过滤 / 转义,允许恶意 JS/HTML 代码提交并持久化存储(如数据库、缓存);当其他用户访问包含该恶意内容的页面时,前端浏览器会将恶意代码当作正常页面代码解析并自动执行,黑客借此窃取用户 Cookie、冒充用户操作或篡改页面内容。核心本质是把不可信的用户输入当作可信的页面代码执行。

2、典型场景:

电商平台商品评论区、社交平台留言框、论坛发帖区、后台管理系统反馈模块(支持用户输入文本的公共 / 私密模块均适用)。

3、流程化攻击步骤:

  • 黑客在电商评论区提交评论,内容为<script>var cookie = document.cookie; 发送数据到黑客服务器(cookie);</script>;
  • 电商系统未做任何处理,直接将该恶意代码存入数据库;
  • 普通用户打开该商品详情页,系统从数据库读取评论并直接渲染到页面;
  • 普通用户的浏览器解析并执行评论中的恶意 JS,自动将用户的登录 Cookie 发送到黑客服务器;
  • 黑客获取 Cookie 后,冒充该普通用户登录电商平台,查看订单、修改收货地址等。

(2)、CSRF跨站请求伪造:

1、核心原理:

用户在目标系统登录后,浏览器会保留有效的会话凭证(Session/Cookie) 且未过期;黑客利用浏览器的 “自动携带同域 Cookie” 特性,搭建恶意页面并诱导用户访问,恶意页面会向目标系统发起跨域伪造请求(如改密码、转账);目标系统仅通过 Cookie 验证用户登录状态,未校验请求是否为用户主动 / 自愿发起,误将伪造请求当作用户本人操作执行。核心本质是利用有效会话 + 无请求合法性校验,冒充用户发起非自愿操作。

2、典型场景:

银行/支付平台转账、电商平台修改收货地址/确认下单、任意系统修改密码/绑定手机号、后台管理系统删除数据(需登录后执行的写操作均适用)。

3、流程化攻击步骤:

  • 用户打开招商银行官网,输入账号密码登录,浏览器保存招行的登录 Cookie(未退出、未过期);
  • 用户未关闭浏览器,无意间点击了黑客发送的 “免费领取话费” 链接,跳转到黑客搭建的恶意页面;
  • 恶意页面加载后,自动向招行后台发起 POST 请求:https://cmb.com/transfer?to=黑客账号&money=5000,浏览器会自动携带招行的登录 Cookie;
  • 招行后台仅校验 Cookie 是否有效(发现用户已登录),未做其他验证,直接执行转账操作;
  • 用户银行卡被转走 5000 元,全程无感知,未主动操作过转账。

(3)、会话固定:

1、核心原理:

目标系统存在**“未登录即可生成有效 SessionID”**且**“用户登录后不更换 SessionID”**的双重问题;黑客先访问目标系统获取一个合法的 SessionID,通过链接、二维码等方式诱骗用户使用该 SessionID 访问系统并完成登录;由于登录前后 SessionID 未变,黑客持有的该 SessionID 会被绑定到用户的登录状态,后续黑客直接使用该 SessionID 即可冒充用户登录系统,获取用户权限。核心本质是登录不更换 SessionID,导致黑客提前获取的无效 SessionID 被绑定为有效登录凭证。

2、典型场景:

所有基于 Session 做登录状态管理的 Web 系统(尤其是未做 Session 安全配置的系统),如电商、管理后台、社交平台。

3、流程化攻击步骤:

  • 黑客先访问某电商平台(无需登录),平台为其生成合法 SessionID:JSESSIONID=123456,黑客保存该 ID;
  • 黑客将带该 SessionID 的链接发给用户:https://shop.com?JSESSIONID=123456;
  • 用户点击该链接访问电商平台,输入自己的账号密码完成登录;
  • 电商平台未更换 SessionID,仍使用123456,并将该 ID 绑定到用户的登录状态;
  • 黑客在自己的浏览器中设置 Cookie 为JSESSIONID=123456,访问电商平台,直接以该用户身份登录,可查看订单、修改信息。

除此之外,Web开发中还有诸多典型高危安全漏洞,比如同权限用户间可通过修改请求 ID 访问他人数据的水平越权、低权限用户可直接访问高权限接口执行高危操作的垂直越权,利用页面嵌套和视觉欺骗诱导用户非自愿操作的点击劫持,密码在网络传输或数据库存储中未做安全加密易被窃取的密码明文传输/弱存储,敏感接口未做任何认证授权校验可被匿名访问的未授权访问,以及黑客通过窃取有效 SessionID 冒充用户登录的会话劫持,这些漏洞均因系统在权限校验、数据防护、会话管理、页面安全等方面的配置或逻辑缺失引发,是 Web 安全防护中需重点关注的要点。

2、常见认证方式:

认证方式

核心原理

典型特点/实现

适用场景

账号密码认证

(含HTTP BASIC)

用户输入账号+密码,服务端校验与存储的加密密码是否一致

最基础的认证思路;

HTTP BASIC是其 HTTP 协议原生实现(账号:密码经 Base64 编码放入请求头)

所有系统基础登录、内部低安全需求简单服务

Session-Cookie认证

账号密码校验通过后,服务端生成 SessionID 并存储用户登录状态,客户端通过 Cookie 保存 SessionID,后续请求自动携带完成身份识别

服务端有状态(需存储会话信息);

Spring Security默认认证方式;

适配HTTP无状态特性

传统单体 Web 项目(SSM/SSH 架构)

Token(JWT)认证

账号密码校验通过后,服务端生成加密令牌返回客户端,后续请求携带令牌完成校验,服务端无需存储令牌及用户状态

服务端无状态;

主流实现为 JWT(可自定义携带用户基础信息、设置过期时间);

令牌通常存请求头/客户端本地存储

前后端分离项目、微服务架构、移动端 APP / 小程序

API密钥认证

(AppKey/AppSecret)

为调用方分配唯一 AppKey(公开身份标识)+AppSecret(私密签名密钥),请求时通过密钥对请求签名,服务端验签通过即完成认证

双密钥机制;

无令牌生成流程,使用固定密钥做请求签名;

服务端需存储密钥对用于验签

服务间调用、开放平台API、第三方系统对接、内部微服务通信

OAuth2.0

第三方授权认证

基于OAuth2.0协议,通过微信/支付宝/QQ等第三方已认证的账号完成授权,获取用户唯一标识即可实现登录

免注册快捷登录;

无需自身系统管理用户账号密码;

衍生OpenID Connect协议增强身份认证能力

C端产品、大众端应用、小程序、各类社交/电商APP快捷登录

3、相关框架:

框架

核心优势

主要不足

适用场景

Spring Security

Spring生态原生无缝集成,Spring Boot/Cloud自动配置开箱即用;

原生内置OAuth2.0、SSO、CSRF/CORS防护等企业级功能;

天生适配微服务无状态设计;

支持URL/方法/数据级细粒度权限控制

学习成本高,配置细节繁琐;

非Spring生态项目适配性差,轻量项目使用有功能冗余

Spring Boot/Cloud微服务架构、企业级复杂系统、金融/政务等高安全需求场景、需原生SSO/第三方授权的项目

Apache Shiro

轻量易用,学习/配置成本极低;

跨框架通用无依赖(支持Spring/JavaSE等);

组件解耦度高,自定义扩展简单无侵入

高级功能(OAuth2.0/SSO)需集成第三方组件;

无原生微服务/分布式支持,需手动改造;

仅原生支持URL/方法级授权,数据级需自定义

单体Web项目、中小规模系统、非Spring生态跨框架项目、快速开发上线的常规认证授权需求场景

Sa-Token

国产轻量安全框架,极简 API、零配置开箱即用;

原生支持微服务分布式、单点登录 SSO、OAuth2.0、 jwt、无感刷新、同端互斥登录;

适配 Spring Boot/Cloud,适配性极强,上手成本远低于前两者;

内置防重放、防爬虫、账号封禁、二级认证等常用功能

行业老牌大厂标准化落地案例少于 Spring Security;

小众技术栈适配生态稍弱;

超大型复杂权限模型不如 Security 原生灵活

中小型微服务、创业项目、快速开发项目、不想啃复杂配置的 Spring 项目、需要快速落地 SSO/OAuth2 又不想折腾整合的项目

二、Spring Security 6 快速入门:

1、项目结构:

1

环境/工具

版本要求

说明

JDK

Java 17

Spring 6 最低要求 Java 17,Java 8/11 无法兼容

2、引入依赖:

<!-- Spring 6 最低要求 Java 17-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

3、创建控制器:

@RestController
@RequestMapping("v1")
public class BasicController {

    /**
     * http://localhost:8080/v1/hello
     *
     * @return
     */
    @GetMapping("/hello")
    public String hello() {
        return "Hello SpringSecurity6";
    }

}

4、访问资源:

引入 spring-boot-starter-security 依赖后,Spring Security 会基于 Spring Boot 自动配置机制默认生效,全局拦截所有匹配 /** 路径的 HTTP 请求;当未认证用户访问受保护资源时,框架将自动重定向至其内置的 GET /login 登录页面完成身份认证。

发起请求->跳转到框架内置的登录页面:

http://localhost:8080/v1/hello

默认用户名:

user

密码:

项目启动时控制台打印的随机UUID

2

3

5、自定义登录用户、密码与角色:

Spring Security 默认提供的 user 用户名 + 随机密码临时用户体系,仅适用于开发阶段的快速验证场景,无法满足实际业务中自定义身份凭证、密码加密存储、角色权限分配等核心需求。为此,我们提供两种自定义登录用户、密码及角色的实现方案,两种方案适用场景不同,且配置优先级明确:Java 配置类优先级高于 YAML 配置

(1)、方式一:基于 YAML 配置文件自定义

该方案无需编写 Java 配置类,仅通过配置文件即可快速自定义默认用户的账号、密码与角色,适用于本地开发快速测试场景。

1)、核心局限性:

仅支持单用户配置、密码仅能以明文形式存储、无法实现角色与资源的精细化权限管控,不支持对接数据库等持久化存储方案,仅可作为临时测试手段,严禁用于生产环境。

2)、配置示例:

spring:
  security:
    user:
      # 自定义用户名
      name: admin
      # 自定义密码
      password: 123456
      # 自定义用户角色(仅支持给单用户配置,多角色用英文逗号分隔如ADMIN,USER)
      roles: ADMIN

3)、测试接口示例:

开启方法级权限校验(@EnableMethodSecurity),编写测试接口验证用户登录状态与角色权限:

@EnableMethodSecurity
@RestController
@RequestMapping("v2")
public class BasicYmlController {

    // 无需角色,仅需登录即可访问(验证用户登录是否生效)
    @GetMapping("/hello")
    public String hello() {
        return "登录成功!当前访问的是通用接口";
    }

    // 仅ADMIN角色可访问(验证角色配置是否生效)
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/admin/hello")
    public String adminHello() {
        return "登录成功!当前访问的是ADMIN角色专属接口";
    }

    // 仅USER角色可访问(验证角色配置是否生效)
    @PreAuthorize("hasRole('USER')")
    @GetMapping("/user/hello")
    public String userHello() {
        return "登录成功!当前访问的是USER角色专属接口";
    }

}

4

(2)、方式二:基于配置类 + @Bean 自定义

YAML 配置的局限性无法满足生产环境的安全规范与业务复杂度要求,基于 Java 配置类 + @Bean 的实现方案是生产环境标准方案。

该方案完全弥补了 YAML 配置的短板,支持密码加密、多用户多角色配置、角色与资源精细化权限绑定等核心能力;同时配置优先级更高,若两种配置方式同时启用,YAML 配置的用户信息会被直接覆盖失效

1)、核心配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

/**
 * Spring Security 6 核心配置类
 *
 * @Configuration:标识该类是Spring配置类,Spring启动时自动加载该类的所有配置
 * @EnableWebSecurity:启用Spring Security的Web安全功能,必须添加,否则Security不生效
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    /**
     * 1. 密码编码器(Spring Security 6 必须指定,否则启动报错)
     * 作用:对用户密码进行加密存储,避免明文存储(明文存储存在极大安全隐患)
     *
     * BCryptPasswordEncoder:Spring官方推荐的密码加密方式,不可逆,安全性高
     * 特点:相同明文密码,每次加密后的结果都不同(自带随机盐值)
     * @Bean:将该方法的返回值(密码编码器)交给Spring容器管理,后续其他地方可直接注入使用
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        // 返回BCrypt密码编码器实例,后续所有密码加密、校验都用该编码器
        return new BCryptPasswordEncoder();
    }

    /**
     * 2. 基于内存的用户信息
     * 作用:模拟用户数据,用于测试认证、授权功能
     *
     * UserDetailsService:Spring Security提供的接口,用于加载用户信息(用户名、密码、角色)
     * 本阶段创建2个测试用户,用于验证角色权限:
     * - 普通用户:username=user,password=123456,角色=USER(只能访问普通接口)
     * - 管理员用户:username=admin,password=123456,角色=ADMIN(可访问所有接口)
     */
    @Bean
    public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
        // 普通用户(角色USER)
        // 设置用户名
        UserDetails user = User.withUsername("user")
                // 密码必须加密:使用上面定义的密码编码器,对明文密码"123456"进行加密
                // 注意:Spring Security 6 禁止明文密码,必须加密,否则登录失败
                // {noop} 的含义:No Operation Password Encoder,表示不对密码进行任何加密处理
                // .password("{noop}123456")
                .password(passwordEncoder.encode("123456"))
                // 方式一:配置用户资源访问权限
//                .authorities("USER_RESOURCE")
                // 方式二:配置用户角色,Spring会自动给角色添加前缀 ROLE_(数据库存储时无需加)
                .roles("USER")
                // 构建用户对象
                .build();

        // 管理员用户(角色ADMIN)
        UserDetails admin = User.withUsername("admin")
                .password(passwordEncoder.encode("123456"))
//                .authorities("ADMIN_RESOURCE")
                .roles("ADMIN")
                .build();

        // 将用户信息存入内存,返回内存级别的用户详情服务(后续替换为数据库查询)
        return new InMemoryUserDetailsManager(user, admin);
    }

    /**
     * 3. 安全过滤链(核心:配置接口权限、登录登出行为)
     * 作用:拦截所有HTTP请求,根据配置的规则,校验请求的权限(是否需要登录、是否有对应角色)
     *
     * HttpSecurity:用于配置安全规则(接口权限、登录页、登出逻辑等)
     * SecurityFilterChain:Spring Security 6 新API,用于封装所有安全过滤规则,返回后生效
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 配置HTTP请求的安全规则,链式编程,配置完成后返回SecurityFilterChain实例
        http
                // 关闭CSRF防护
                // CSRF:跨站请求伪造防护,关闭后可避免前端调用接口时报403错误
                .csrf(csrf -> csrf.disable())
                // 配置接口访问权限规则(核心,控制哪些接口能访问、哪些需要认证/角色)
                .authorizeHttpRequests(auth -> auth
                        // 1. 匿名可访问接口:/v3/hello(无需登录,任何人都能访问)
                        // /login:Spring Security默认登录页地址,必须允许匿名访问(否则未登录无法访问登录页)
                        .requestMatchers("/v3/hello", "/login").permitAll()
                        // 2. 需指定角色可访问接口:所有以 /v3/admin/ 开头的接口,必须拥有ADMIN角色
                        //.requestMatchers("/v3/admin/**").hasAuthority("ADMIN_RESOURCE")  // 对应配置:.authorities("ADMIN_RESOURCE")
                        .requestMatchers("/v3/admin/**").hasRole("ADMIN")
                        // 3. 其他所有接口:必须登录认证(无论什么角色)后,才能访问
                        .anyRequest().authenticated()
                )
                // 方式一:自定义配置登录成功/失败处理器,返回JSON格式认证结果
//                .formLogin(form -> form
//                        .successHandler((request, response, authentication) -> {
//                            response.setContentType("application/json;charset=UTF-8");
//                            response.getWriter().write("{\"code\":200,\"message\":\"登录成功\"}");
//                        })
//                        .failureHandler((request, response, exception) -> {
//                            response.setContentType("application/json;charset=UTF-8");
//                            response.setStatus(401);
//                            response.getWriter().write("{\"code\":401,\"message\":\"登录失败\"}");
//                        })
//                )
                // 方式二:使用默认表单登录配置
                .formLogin(Customizer.withDefaults())
                // 使用默认登出配置
                .logout(Customizer.withDefaults());
        return http.build();
    }
}

注:

加密实现类

核心特点

适用场景

优缺点

BCryptPasswordEncoder

基于 BCrypt 哈希算法,自动生成随机盐值(无需手动管理盐);不可逆加密;计算慢(抗暴力破解)

99%的生产场景(Web 应用、微服务、企业系统)

优点:安全、自带盐值、Spring 官方推荐;

缺点:计算速度慢(但这也是安全的体现)

SCryptPasswordEncoder

基于 SCrypt 算法,比 BCrypt 更安全(内存密集型,抗 ASIC/GPU 破解);同样自动生成盐值

高安全要求场景(金融、政务、支付系统)

优点:安全性高于 BCrypt;

缺点:计算 / 内存消耗更大,普通系统没必要

Pbkdf2PasswordEncoder

基于 PBKDF2 算法,符合 NIST(美国国家标准与技术研究院)规范;自动加盐

需符合特定合规要求的场景(如政府 / 金融行业合规)

优点:合规性强;

缺点:安全性略低于 BCrypt/SCrypt

Argon2PasswordEncoder

基于 Argon2 算法(2015 年密码哈希竞赛冠军);内存 + CPU 密集型,抗破解能力最强

超高安全要求场景(如密码管理器、区块链钱包)

优点:目前最安全的哈希算法;

缺点:JDK11 + 才支持,资源消耗大

NoOpPasswordEncoder

无加密(明文存储);仅兼容旧系统,已标记为 @Deprecated(废弃)

仅本地测试(绝对禁止生产)

优点:测试方便;

缺点:完全不安全,生产用会直接泄露密码

MessageDigestPasswordEncoder

基于 MD5/SHA-1 等哈希算法(无盐 / 固定盐)

仅兼容极老旧系统(如遗留项目)

优点:兼容旧系统;

缺点:无盐值,易被彩虹表破解,已淘汰

盐值:随机字符串,作用是和密码混合加密,避免相同密码生成相同密文;

2)、测试接口示例:

@RestController
@RequestMapping("v3")
public class BasicBeanController {

    /**
     * 1. 匿名可访问接口(无需登录,任何人都能访问)
     */
    @GetMapping("/hello")
    public String hello() {
        return "Hello,您无需登录,任何人都能访问(匿名访问接口)";
    }

    /**
     * 2. 需登录认证接口(必须登录,无论什么角色,登录即可访问)
     * 未登录访问:会自动跳转到 Spring Security 默认登录页
     * 登录后访问:返回正常响应内容
     */
    @GetMapping("/user/info")
    public String userInfo() {
        return "Hello, User! 你已成功登录,可访问该需认证接口~";
    }

    /**
     * 3. 需指定角色接口(必须登录,且登录用户拥有 ADMIN 角色,否则无权访问)
     * 普通用户登录访问:返回 403 Forbidden(无权访问)
     * 管理员用户登录访问:返回正常响应内容
     */
    @GetMapping("/admin/info")
    public String adminInfo() {
        return "Hello, Admin! 你是管理员(ADMIN角色),可访问该权限接口~";
    }

}

5

三、Spring Security 6 的相关过滤器链:

Spring Security 6 的 Web 安全基于Servlet 过滤器链实现,核心由FilterChainProxy(核心代理)与SecurityFilterChain(具体安全链)组成,形成 “单代理多链” 的灵活架构。

  • FilterChainProxy:全局唯一的 Servlet Filter(注册名为springSecurityFilterChain),负责分发请求到匹配的 SecurityFilterChain
  • SecurityFilterChain:多条独立安全链(按order排序),每条包含RequestMatcher(请求匹配规则)+ 过滤器列表,仅匹配请求才会进入对应链Spring
  • FilterOrder:Spring Security 6 通过SecurityFilterOrder枚举严格定义过滤器执行顺序,确保依赖关系正确

1、默认过滤器:

标准 Spring Boot+Spring Security Starter默认加载的 15 个过滤器,以下核心过滤器按执行顺序排列

序号

过滤器全类名

核心作用

启用条件

1

DisableEncodeUrlFilter

禁用 URL 重写编码,防止会话 ID 拼接至 URL 导致的安全风险

自动启用(默认)

2

WebAsyncManagerIntegrationFilter

整合 Spring Web 异步请求与 SecurityContext,确保异步线程可访问安全上下文

WebMvc 环境下自动启用

3

SecurityContextHolderFilter

管理请求生命周期的 SecurityContext,请求开始初始化空上下文,请求结束清空上下文,替代 Spring Security 5 的 SecurityContextPersistenceFilter,默认不绑定 HttpSession

自动启用(默认)

4

HeaderWriterFilter

向响应头注入安全相关字段(如 X-Content-Type-Options、X-Frame-Options、X-XSS-Protection),防范常见 Web 安全漏洞

自动启用(默认)

5

CorsFilter

基于配置的 CORS 规则,处理跨域请求预检(OPTIONS 请求)及跨域请求校验

Spring MVC 环境下自动启用,可通过 cors() 配置自定义规则

6

CsrfFilter

校验请求中的 CSRF 令牌,拦截未携带有效令牌的非安全 HTTP 方法(POST、PUT、DELETE 等),防范跨站请求伪造攻击

默认启用,可通过 csrf().disable() 禁用

7

LogoutFilter

拦截默认登出请求(POST /logout),执行登出逻辑:清空 SecurityContext、销毁会话、清除认证信息

自动启用,可通过 logout() 配置自定义登出路径、成功跳转页

8

UsernamePasswordAuthenticationFilter

拦截表单登录请求(默认 POST /login),提取用户名/密码,执行认证逻辑,生成 Authentication 对象并存入 SecurityContext

自动启用,可通过 formLogin() 配置自定义登录路径、参数名

9

DefaultLoginPageGeneratingFilter

当未配置自定义登录页时,自动生成默认登录页面(包含用户名、密码输入框及登录逻辑)

未自定义登录页时自动启用,配置formLogin().loginPage() 后自动禁用

10

BasicAuthenticationFilter

处理 HTTP Basic 认证,提取请求头中的 Authorization 信息,解析用户名/密码并执行认证

自动启用,可通过 httpBasic().disable() 禁用

11

RequestCacheAwareFilter

缓存用户未认证时的请求,待用户认证通过后,自动重放该请求至目标资源,提升用户体验

自动启用

12

SecurityContextHolderAwareRequestFilter

包装原生 HttpServletRequest,提供安全相关的请求方法(如 isUserInRole()),适配 Servlet 规范的安全接口

自动启用

13

AnonymousAuthenticationFilter

为未认证的请求生成匿名 Authentication 对象(匿名身份标识为 anonymousUser),确保 SecurityContext 中始终有 Authentication 对象

自动启用

14

ExceptionTranslationFilter

捕获过滤器链中抛出的认证异常(AuthenticationException)和授权异常(AccessDeniedException),统一转换为 HTTP 响应(401 未认证、403 无权限)或触发认证入口

自动启用,是安全异常处理的核心过滤器

15

AuthorizationFilter

Spring Security 6 核心授权过滤器,替代 Spring Security 5 的 FilterSecurityInterceptor,基于 AuthorizationManager 执行访问决策,校验当前认证主体是否拥有请求资源的权限

自动启用,是权限校验的最终执行载体

2、核心请求时序图:

 6

四、表单登录的认证流程:

 7

1、前端发起登录:

客户端以 POST 方式提交包含用户名、密码的表单数据,请求 Spring Security 默认登录接口 /login。

2、过滤器拦截:

请求进入 Spring Security 过滤器链,被 UsernamePasswordAuthenticationFilter(账号密码登录过滤器) 拦截,作为认证流程入口,调用 attemptAuthentication 方法启动认证逻辑。

3、封装临时认证对象:

过滤器从请求参数中提取用户名与密码,封装为未认证状态的 UsernamePasswordAuthenticationToken(账号密码认证令牌),作为本次认证的上下文载体。

4、交给认证管理器处理:

过滤器将未认证令牌提交至 AuthenticationManager(认证管理器)(默认实现为 ProviderManager(认证提供者管理器)),由其通过 authenticate 方法发起认证,并根据令牌类型匹配合适的 AuthenticationProvider(认证提供者) 实现。

5、查询内存/数据库用户信息:

ProviderManager(认证提供者管理器) 匹配到专用的 DaoAuthenticationProvider(账号密码认证处理器),该处理器调用 retrieveUser 方法,通过 UserDetailsService(用户详情服务) 实现类从内存 / 数据库加载用户数据,返回包含凭证、权限及账号状态的 UserDetails(用户详情对象) 实例。

6、密码比对校验:

DaoAuthenticationProvider(账号密码认证处理器) 调用 additionalAuthenticationChecks 方法,基于配置的 PasswordEncoder(密码编码器) 完成前端明文密码与加密凭证的比对校验。

7、账号状态校验:

同时自动校验账号状态(锁定、过期、禁用)与凭证有效性,任一条件不满足则直接判定认证失败。

8、认证成功处理:

所有校验通过后,DaoAuthenticationProvider(账号密码认证处理器) 构建已认证状态的 Authentication(认证身份对象),存入 SecurityContextHolder(安全上下文持有者) 安全上下文,为后续授权过滤器提供用户身份信息,并执行预设的登录成功逻辑。

9、认证失败处理:

若用户名不存在、密码不匹配或账号状态异常,认证过程会抛出对应 AuthenticationException(认证异常),触发预设的登录失败处理逻辑。

10、响应前端:

认证流程结束后,UsernamePasswordAuthenticationFilter(账号密码登录过滤器) 根据认证结果,向前端返回登录成功 / 失败响应,本次登录请求处理完成。

 

posted on 2026-06-24 00:18  爱文(Iven)  阅读(0)  评论(0)    收藏  举报

导航