Spring Security基础:快速搭建安全认证系统
开篇:Spring Security是什么,用来做什么?

你是否曾好奇,为什么我们登录一个网站时,系统会记住你是谁?为什么某些页面你没权限就打不开?这背后其实有一整套“安全验证”的逻辑在起作用。而 Spring Security 就是 Java 开发中最常用于实现这套安全验证机制的框架。
简单来说,Spring Security 就是用来保护你的网页或接口不被随便访问的一把“锁”。它可以帮助你实现:
- 用户登录功能(认证)
- 不同用户有不同访问权限(授权)
- 防止攻击行为(比如暴力破解、跨站脚本等)
在这篇教程中,我会带大家从零开始,一步步用 Spring Security 搭建一个简单的安全认证系统。即使你是编程新手也不用担心,我们会从头教起,手把手带你写代码!
环境准备:搭建开发环境

在正式开始之前,我们需要准备好开发工具和相关依赖。下面是一个清晰的操作指南。
1. 安装 JDK
首先确认你已经安装了 Java 开发工具包(JDK),推荐版本为 JDK 17 或以上。
如何检查:
打开命令行(Windows 是 cmd 或 PowerShell,Mac 是终端)输入:
java -version
如果你看到类似如下的信息,说明安装好了:
openjdk version "17.0.6" 2023-01-17
如果没有安装,请前往 Oracle官网 或使用像 Adoptium 这样的开源 JDK 提供商下载安装。
2. 安装 IDE(推荐 IntelliJ IDEA)
IntelliJ IDEA 是 Java 开发中最常用的集成开发环境(IDE),免费的 Community 版本就能满足我们的需求。
下载地址:https://www.jetbrains.com/idea/download/
安装完成后启动它。
3. 创建一个新的 Spring Boot 项目
打开 https://start.spring.io/,这是一个官方提供的 Spring Boot 项目生成器。
选择以下配置:
- Project: Maven
- Language: Java
- Spring Boot Version: 建议选 3.x 的稳定版本
- Group: com.example (这是项目组织名)
- Artifact: security-demo (这是项目名)
- Dependencies: 添加两个:
Spring WebSpring Security
点击下方的 “Generate” 下载项目压缩包。
解压后,用 IntelliJ 打开这个文件夹即可看到初始项目结构。
4. 启动项目测试
找到 SecurityDemoApplication.java 文件,在右侧点击运行按钮或者使用快捷键运行它。
等待控制台出现如下内容表示启动成功:
Tomcat started on port(s): 8080 (http)
浏览器访问 http://localhost:8080,你会看到一个默认错误页(因为还没定义任何页面)——但这说明你的基本开发环境已经搭建完成!
核心概念:通俗理解 Spring Security 的关键知识点

在真正动手前,我们先来简单了解几个核心术语,这样在后面学习的时候不会晕菜。
1. 认证(Authentication)
简单说,就是判断一个人是谁。比如你登录微信时输入账号密码,就是在做认证。
Spring Security 中的认证过程包括:
- 用户提交账号密码
- 系统验证信息是否正确
- 如果正确,就允许访问资源
2. 授权(Authorization)
授权的意思是:“虽然我知道你是谁,但你能访问哪些东西呢?”
例如:
- 普通用户只能看主页
- 管理员可以看到后台数据
3. 用户凭证(User Details)
就是用户的信息,通常包括用户名、密码、角色(role)等。Spring Security 中通过 UserDetailsService 来加载这些信息。
4. 过滤器链(Filter Chain)
就像一道道门卫,对每个请求进行检查。Spring Security 使用多个过滤器来做不同的安全处理。
比如:
- 第一个过滤器负责检查是否已经登录
- 第二个负责记录日志
- 第三个负责防止攻击……
我们可以自定义这些过滤器来做更复杂的控制。
实战项目:一步一步构建安全系统
接下来我们将创建一个简单的 Spring Boot 应用,包含以下功能:
- 提供一个登录页面
- 用户登录后可以访问
/home - 未登录访问该页面则重定向到登录页
- 演示管理员与普通用户的权限差异
第一步:创建简单的控制器
新建一个类 HomeController.java 放在 com.example.securitydemo.controller 包下:
package com.example.securitydemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeController {
@GetMapping("/")
public String index() {
return "欢迎来到首页!请 <a href=\"/login\">登录</a>";
}
@GetMapping("/home")
public String home() {
return "你已成功登录!这里是主页";
}
}
现在你可以重启应用,并访问 http://localhost:8080 和 http://localhost:8080/home 测试一下,默认都能直接访问。
接下来我们要启用 Spring Security 来限制访问。
第二步:添加 Spring Security 配置类
创建一个新的类 SecurityConfig.java 在 com.example.securitydemo.config 包下:
package com.example.securitydemo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// 定义内存中的用户
@Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("123456")
.roles("USER")
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("admin")
.password("admin123")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
// 设置 URL 访问权限规则
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/").permitAll()
.requestMatchers("/home").authenticated()
)
.formLogin(login -> login
.loginPage("/login") // 自定义登录页路径
.defaultSuccessUrl("/home", true)
.permitAll()
)
.logout(logout -> logout.permitAll());
return http.build();
}
}
上面的代码主要做了三件事:
- 配置了两个内存用户:一个普通用户(user / 123456),一个管理员(admin / admin123)
- 设置了 URL 访问权限:首页所有人可访问,
/home只有登录用户才能访问 - 启用了表单登录界面(稍后我们会创建登录页面)
⚠️ 注意:这里我们为了演示方便,采用的是最简单的内存方式存储用户信息,实际项目中一般会从数据库读取用户信息。
第三步:创建登录页面
在 resources/templates 目录下创建一个名为 login.html 的文件(记得先创建 templates 目录):
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h3>请登录</h3>
<form action="/login" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
<p th:text="${error}" style="color:red;"></p>
</body>
</html>
然后在之前的 HomeController 中添加一个方法,展示这个登录页面:
@GetMapping("/login")
public String login() {
return "login";
}
重启程序,再次访问:
- http://localhost:8080 —— 无需登录就可以看到“欢迎首页”
- http://localhost:8080/home —— 会被跳转到登录页
- 登录成功后跳转至
/home
尝试用 user / 123456 登录看看!
第四步:基于角色设置权限
刚才的例子只是实现了最基本的认证功能。我们现在升级一下:让 /admin 路径只能由 ADMIN 角色访问。
修改 SecurityConfig 类中的权限配置部分:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/").permitAll()
.requestMatchers("/home").authenticated()
.requestMatchers("/admin").hasRole("ADMIN") // 新增这一行
)
.formLogin(login -> login
.loginPage("/login")
.defaultSuccessUrl("/home", true)
.permitAll()
)
.logout(logout -> logout.permitAll());
return http.build();
}
同时,在 HomeController 中增加一个新方法:
@GetMapping("/admin")
public String adminHome() {
return "欢迎管理员!这里是私密区域";
}
重启服务后,用 admin / admin123 登录访问 /admin,再用普通用户访问,看看效果。
常见问题:新手容易踩坑的地方
1. 为什么会提示 “Bad credentials”?
这通常是用户名或密码不对。注意 Spring Security 默认要求用户名区分大小写,密码也要完全匹配。
解决办法:
- 检查是否输入了正确的用户名和密码
- 确保没有多余的空格
- 检查
SecurityConfig中的密码是否正确
2. 页面访问一直跳回登录页,怎么回事?
可能是权限配置搞错了。比如你想访问 /home,但忘记加 .authenticated()。
解决办法:
- 查看 SecurityConfig 中的路径匹配规则
- 确保对应路径的访问权限设置正确
3. Thymeleaf 报错 Could not parse as expression
如果你在登录页面中加入了 <p th:text="${error}">,但在没有引入 Thymeleaf 插件的情况下会出错。
解决办法:
- 暂时不加这段代码,或者
- 添加 Thymeleaf 依赖(可以在 start.spring.io 再添加一次依赖)
4. 表单提交报错:CSRF token missing
Spring Security 默认开启 CSRF 防护,也就是防止别人偷偷发送请求。如果你自己写的登录页面没有加上 Token 验证就会出错。
解决办法:
- 在页面中加入隐藏字段:
<input type="hidden" name="_csrf" th:value="${_csrf.token}">
或者临时关闭 CSRF(仅限练习环境):
在 SecurityConfig 的最后加上:
.csrf(csrf -> csrf.disable())
⚠️ 生产环境中不要禁用 CSRF!
学习建议:下一步学什么?
恭喜你完成了第一个安全系统的基础搭建!你已经掌握了:
- Spring Security 的基本原理
- 用户认证和角色管理
- 控制 URL 的访问权限
- 简单的登录页面设计
接下来你可以继续深入学习以下几个方向:
🧪 一、实战进阶
- 【实操】使用数据库存储用户信息(如 MySQL + Spring Data JPA)
- 【实操】实现注册功能 + 邮箱验证码
- 【实操】使用 JWT 做无状态身份验证(适用于前后端分离架构)
🔐 二、安全增强
- 学习 Spring Security 中的 OAuth2 协议(支持 GitHub 登录等第三方登录)
- 加入 RBAC(基于角色的权限管理)模型
- 学习 CSRF、XSS 攻击防护机制
🛠 三、技术提升
- 学习 AOP 在权限控制中的应用
- 配合 Redis 缓存用户 session
- 使用 Spring Security Test 做单元测试
总结
这篇文章我们从零开始搭建了一个使用 Spring Security 的安全系统,包括用户登录、权限管理、URL 控制等功能。希望你在这个过程中不仅学会了“怎么用”,也理解了“为什么这么做”。
如果你还有疑问或者想继续深入学习,欢迎留言交流。接下来我们还会分享更多关于 Spring Security 高级用法的内容,别忘了关注更新哦!
📌 附:完整代码结构概览
security-demo/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com.example.securitydemo/
│ │ │ ├── controller/
│ │ │ │ └── HomeController.java
│ │ │ ├── config/
│ │ │ │ └── SecurityConfig.java
│ │ │ └── SecurityDemoApplication.java
│ │ ├── resources/
│ │ │ ├── templates/
│ │ │ │ └── login.html
│ │ │ └── application.properties
✅ 看到这里,你已经完成了第一关!给自己点个赞吧!继续加油,成为 Spring 安全领域的高手!🚀

评论 0