SpringSecurity 从入门到实战:认证授权、权限控制、JWT 全解析

SpringSecurity 从入门到实战:认证授权、权限控制、JWT 全解析

在前后端分离、微服务架构成为主流的今天,系统的认证与授权是保障接口安全的核心环节。SpringSecurity 作为 Spring 生态原生的安全框架,凭借其 “开箱即用、高度可扩展” 的特性,成为 Java 后端开发者实现系统安全的首选工具。

本文面向SpringSecurity 零基础 / 入门级开发者,从基础概念到实战落地,全程拆解 SpringSecurity 核心功能(认证、授权、RememberMe、JWT 等),所有代码均基于securitdemo项目(文末附完整工具类代码),步骤细化到 “复制即可运行”,同时补充实战中常见的坑点与解决方案,帮你一站式掌握 SpringSecurity 核心用法。

认证授权概述

认证授权概念

很多人容易混淆 “认证” 和 “授权”,用通俗的话解释:

  • 认证(Authentication): 验证 “你是谁”—— 比如登录时输入用户名密码,系统校验是否为合法用户;

  • 授权(Authorization): 验证 “你能做什么”—— 认证通过后,系统判断你是否有权限操作某个接口 / 资源(比如普通用户不能访问管理员后台)。

两者的执行顺序:先认证,后授权;认证失败直接拒绝访问,认证成功才会进入授权校验环节。

RBAC权限模型

RBAC(Role-Based Access Control,基于角色的访问控制)是企业级项目中最常用的权限模型,核心是 “用户 - 角色 - 权限” 的三层关联:

核心实体作用示例
用户(User)系统的操作者张三、李四
角色(Role)一组权限的集合管理员、普通用户、运营
权限(Permission)操作资源的最小单元新增用户、删除订单、查看报表

关联逻辑: 给用户分配角色,给角色分配权限,用户通过角色间接拥有权限。

优势: 权限管理解耦(比如 “管理员” 角色的权限变更时,所有分配该角色的用户自动生效),适配企业级复杂权限场景。

常见认证方式

认证方式适用场景优缺点
用户名 + 密码后台管理系统、内部系统简单易实现;安全性依赖密码复杂度
短信 / 邮箱验证码移动端 APP、用户登录无需记忆密码;依赖短信 / 邮箱服务
OAuth2.0(第三方登录)面向 C 端的系统(如电商、社交)提升用户体验;需对接第三方平台
JWT 令牌前后端分离、微服务无状态、跨域;需处理令牌过期 / 注销
Session 认证传统单体应用简单;分布式场景下需共享 Session

SpringSecurity简介

安全框架核心特性

SpringSecurity 不是一个 “单一功能组件”,而是一套完整的安全解决方案,核心特性包括:

  1. 认证机制: 支持表单登录、HTTP Basic 认证、OAuth2.0、LDAP 等多种认证方式;
  2. 授权控制: 支持 URL 级、方法级、注解级的精细化权限控制;
  3. 安全防护: 内置 CSRF、XSS、会话固定攻击、点击劫持等防御机制;
  4. 无缝集成: 与 SpringBoot、SpringCloud 深度融合,配置极简;
  5. 高度可扩展: 核心接口(如 UserDetailsService)支持自定义实现,适配各类业务场景。

常用安全框架

特性SpringSecurityShiro
生态融合与 Spring 全家桶无缝集成独立框架,适配所有 Java 项目
功能丰富度功能全面(认证、授权、防护、OAuth2 等)核心功能(认证、授权),轻量
学习成本稍高(配置多、概念多)低(API 简单、文档友好)
适用场景中大型 Spring 体系项目、微服务小型项目、非 Spring 体系项目

SpringSecurity 核心原理

SpringSecurity 的核心是过滤器链(Filter Chain):客户端请求进入后端后,会依次经过多个安全过滤器,每个过滤器负责一个安全功能(比如认证过滤器、授权过滤器、CSRF 过滤器)。

  • 若某一个过滤器校验失败(比如认证过滤器发现用户名密码错误),直接返回错误响应;
  • 所有过滤器校验通过,才会到达 Controller 层处理业务。

快速入门

创建SpringBoot项目

  1. 创建名为SpringSecurityDemo的SpringBoot项目,填写项目的信息后点击下一步:

  2. 这里我们随便选择一个版本号因为后期要更改版本号,也不需要选择模块,好了之后点击创建:

  3. 创建完成后我们修改pom文件中SpringBoot的版本为3.3.5:

  4. 导入依赖:

xml
 <properties>
        <java.version>17</java.version>
        <jjwt.version>0.9.1</jjwt.version>
        <java-jwt.version>4.3.0</java-jwt.version>
        <fastjson.version>2.0.24</fastjson.version>
        <hutool.version>5.8.11</hutool.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
            <version>3.5.5</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>
        <!--支持多表联查的MyBatis Plus-->
        <!-- pom.xml -->
 
        <!--jwt令牌依赖-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>${jjwt.version}</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>${java-jwt.version}</version>
        </dependency>
        <!-- HuTool工具包 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>
 
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <!-- SpringBoot对Redis的支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- 引入Jedis支持 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <!-- 引入Jedis支持 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
    </dependencies>