Spring Security上手指南:30分钟搭建认证系统
大家好,我是你们的老朋友,一个在大厂搬砖三年、业余时间在B站分享技术的Java后端开发者。今天我想和大家聊聊 Spring Security。
为什么写这篇教程?因为我在带实习生和回答粉丝私信时,发现很多人一听到“安全框架”就望而却步,觉得高深莫测。其实我当初学的时候也是一头雾水——配置一堆类、注解满天飞,连最基本的登录都搞不定。但后来我发现,只要抓住核心流程,Spring Security并没有那么难。
更关键的是,现在几乎每个企业级Java项目(尤其是涉及用户、权限、运营后台的系统)都离不开它。哪怕你主要用Python写数据分析脚本,一旦你的工具需要对外提供Web服务(比如给运营团队做一个内部管理系统),你就得考虑安全性。所以,掌握Spring Security,是迈向专业后端开发的重要一步。
这篇文章专为零基础小白设计,我会用最直白的语言、最简短的代码,带你快速跑通一个完整的认证流程。准备好了吗?我们开始!
一、Spring Security到底是什么?
简单说,Spring Security 是一个用于保护Java应用的安全框架。它能帮你做两件事:
- 认证(Authentication):你是谁?比如用户名密码登录。
- 授权(Authorization):你能做什么?比如普通用户只能看自己的数据,管理员可以删用户。
你可以把它想象成小区的门禁系统:
- 保安(Security)先检查你的门禁卡(认证)
- 然后根据你的业主身份(角色),决定你能不能进健身房、地下车库(授权)
💡 小知识:虽然标题提到了Python,但Spring Security是Java生态的工具。不过很多团队会用Python写数据处理/运营工具,而用Java写主业务系统。两者常配合使用。比如:Python脚本处理完数据后,通过API推给Java系统,这时Java端就需要Spring Security来保护这些API不被乱调。
二、环境准备:5分钟搭好开发环境
所需工具清单
| 工具 | 版本建议 | 说明 |
|---|---|---|
| JDK | 17 或 21 | Spring Boot 3.x 需要 JDK 17+ |
| Maven / Gradle | 最新版 | 项目构建工具 |
| IDE | IntelliJ IDEA(推荐)或 VS Code | 写代码用 |
| 浏览器 | Chrome / Edge | 测试登录页面 |
创建项目
最简单的方式是用 Spring Initializr 在线生成项目。
打开网站,选择:
- Project: Maven
- Language: Java
- Spring Boot: 3.2.x(最新稳定版)
- Project Metadata 填你的信息(如 Group:
com.example, Artifact:security-demo)
在 Dependencies 搜索框中添加:
Spring WebSpring Security
点击 Generate 下载 ZIP 包,解压后用IDE打开。
✅ 验证:项目导入后,你应该能看到
pom.xml中包含spring-boot-starter-security依赖。
三、核心概念:3个关键词讲清楚
很多教程一上来就讲 AuthenticationManager、UserDetailsService,新手直接懵了。其实你只需要先理解这三个东西:
1. 用户(User)
系统里的一个账号,有用户名、密码、角色(比如 USER、ADMIN)。
2. 密码编码器(PasswordEncoder)
绝对不要存明文密码! Spring Security 要求密码必须加密存储。最常用的是 BCryptPasswordEncoder,它每次加密结果都不一样(防彩虹表攻击)。
3. 安全配置(SecurityConfig)
这是一个用 @Configuration 标记的类,告诉Spring Security:
- 哪些路径需要登录?
- 哪些路径公开访问?
- 用什么方式登录?(表单 / JSON / OAuth2...)
四、实战项目:从零搭建一个带登录的系统
我们将完成一个极简但完整的项目:
✅ 访问 /public 不用登录
✅ 访问 /admin 必须用 admin 账号登录
第一步:写一个测试接口
在 src/main/java/com/example/securitydemo 下新建 HomeController.java:
@RestController
public class HomeController {
@GetMapping("/public")
public String publicPage() {
return "这是公开页面,所有人都能看!";
}
@GetMapping("/admin")
public String adminPage() {
return "欢迎来到管理员后台!";
}
}
第二步:配置用户和密码
新建 SecurityConfig.java:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// 告诉Spring如何验证用户
@Bean
public UserDetailsService userDetailsService() {
// 创建两个用户:user(普通用户)和 admin(管理员)
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder().encode("123456")) // 密码必须加密!
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("admin123"))
.roles("ADMIN", "USER") // admin 同时拥有两个角色
.build();
return new InMemoryUserDetailsManager(user, admin);
}
// 密码编码器:必须提供!
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// 安全规则配置
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public").permitAll() // 公开访问
.requestMatchers("/admin").hasRole("ADMIN") // 需要 ADMIN 角色
.anyRequest().authenticated() // 其他所有请求都要登录
)
.formLogin(form -> form // 启用表单登录
.loginPage("/login") // 自定义登录页(可选)
.permitAll() // 登录页本身要公开
)
.logout(logout -> logout.permitAll()); // 登出也要公开
return http.build();
}
}
🔍 代码解读:
InMemoryUserDetailsManager:把用户存在内存里(适合演示,生产要用数据库).hasRole("ADMIN"):注意这里写的是ADMIN,但实际存储的角色名是ROLE_ADMIN(Spring自动加前缀)- 表单登录是默认开启的,如果不自定义页面,Spring会给你一个超简陋的登录页
第三步:启动并测试
- 运行
SecurityDemoApplication.main() - 打开浏览器访问:
http://localhost:8080/public→ 直接看到内容 ✅http://localhost:8080/admin→ 自动跳转到登录页
- 输入用户名
admin,密码admin123→ 成功进入管理页 ✅ - 尝试用
user / 123456登录 → 访问/admin会被拒绝 ❌
🎉 恭喜!你已经完成了第一个Spring Security项目!
五、常见问题:新手最容易踩的坑
Q1:为什么登录后还是跳回登录页?
原因:CSRF(跨站请求伪造)保护默认开启,但你的登录请求没带 _csrf token。
解决方案(任选其一):
- 在登录页的
<form>中加入<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> - 或者临时关闭 CSRF(仅开发环境!):
http.csrf(csrf -> csrf.disable());
⚠️ 注意:生产环境千万别关 CSRF!
Q2:密码明明对,却提示“Bad credentials”
原因:密码没有用 PasswordEncoder 加密,或者用了不同的编码器。
检查点:
- 是否在
userDetailsService()中调用了passwordEncoder().encode()? - 是否提供了
PasswordEncoder的@Bean?
Q3:如何自定义登录成功/失败的跳转?
在 formLogin 中配置:
.formLogin(form -> form
.successForwardUrl("/home") // 登录成功跳转
.failureForwardUrl("/login?error") // 失败跳转
)
Q4:我的项目用JSON交互(前后端分离),怎么处理?
关闭表单登录,改用 httpBasic 或自定义过滤器:
.httpBasic(withDefaults()) // 启用 HTTP Basic 认证(适合API)
// 或者完全自己实现登录逻辑(后续进阶内容)
六、学习建议:下一步该学什么?
你现在掌握了Spring Security的基础骨架。但真实项目远比这复杂。我建议按以下路径深入:
1️⃣ 数据库存储用户(别再用内存了!)
- 学习
JdbcUserDetailsManager或自定义UserDetailsService - 把用户、角色、权限存在 MySQL / PostgreSQL 中
2️⃣ 前后端分离认证方案
- JWT(JSON Web Token)集成
- 自定义登录接口返回 token
- 用
OncePerRequestFilter验证 token
3️⃣ 细粒度权限控制
- 方法级权限:
@PreAuthorize("hasRole('ADMIN')") - 动态权限:从数据库读取用户可访问的URL列表
4️⃣ 与OAuth2整合
- 接入微信、GitHub、企业微信登录
- 作为资源服务器保护API
💬 我在B站有一套《Spring Security从入门到放弃》系列(其实是“从入门到精通” 😄),下一期就会讲JWT+Vue3的完整登录流程,欢迎关注!
结语:安全不是功能,而是底线
最后想强调一点:安全不是“加个登录就行”的附加功能,而是系统设计的基石。哪怕你只是给运营团队写一个小工具,只要涉及数据,就必须考虑“谁能看到、谁能修改”。
我见过太多实习生写的内部系统,因为没加认证,导致测试数据被误删、敏感信息泄露。Spring Security 虽然初期有点门槛,但它能让你用最少的代码,获得企业级的安全保障。
希望这篇教程能帮你迈出第一步。记住:所有高手,都是从“Hello World”开始的。
有问题欢迎在评论区留言,我会一一解答。下期见!

评论 0