Spring Security 基础:快速搭建安全认证系统(零基础入门教程)
大家好,我是阿哲,一名在大厂干了3年 Java 后端开发的工程师,业余时间也在 B 站做技术 UP 主。最近收到不少私信,很多刚学完 Spring Boot 的同学问我:“怎么给自己的项目加个登录功能?”、“简历上写了‘熟悉权限控制’,但实际根本没做过怎么办?”
我当初学的时候,也是一头雾水——Spring Security 文档又长又抽象,网上教程要么太浅(只讲“开箱即用”),要么一上来就讲 OAuth2、JWT、RBAC,直接劝退新手。
所以今天,我就用最通俗的语言、最简单的代码,带你从 0 到 1 搭建一个带用户名密码登录的安全系统。哪怕你连“认证”和“授权”都分不清,也能跟着做完!
💡 为什么学这个?
在真实项目中,90% 的后端系统都需要用户登录。掌握 Spring Security 不仅能让你的毕业设计/个人项目更专业,还能写进简历“项目经验”里,面试时也能聊两句安全设计——这可比只会 CRUD 强多了!
一、Spring Security 是什么?能干啥?
简单说:Spring Security 是 Spring 家族里的“保安队长”。
- 它负责两件事:
- 认证(Authentication):你是谁?(比如:输入用户名密码登录)
- 授权(Authorization):你能干什么?(比如:普通用户不能删管理员数据)
📌 类比理解:
就像你去公司上班——
- 门禁刷工牌 = 认证(证明你是员工)
- 进入不同楼层需要不同权限 = 授权(研发只能进 5 楼,财务才能进 8 楼)
二、环境准备(5 分钟搞定)
我们用最主流的组合:Spring Boot + Spring Security + Thymeleaf(简单前端)
所需工具
| 工具 | 版本建议 | 说明 |
|---|---|---|
| JDK | 17 或 21 | 推荐 LTS 版本 |
| IDE | IDEA / VS Code | 能跑 Java 项目就行 |
| 构建工具 | Maven / Gradle | 本文用 Maven |
创建项目(两种方式)
方式 1:Spring Initializr(推荐)
访问 https://start.spring.io,勾选:
- Spring Web
- Spring Security
- Thymeleaf(用于简单页面展示)
方式 2:手动添加依赖(Maven)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Thymeleaf 额外支持 Spring Security 标签 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
</dependencies>
✅ 避坑指南:
很多人漏加thymeleaf-extras-springsecurity6,导致前端无法显示登录状态!记住:前端想用 Security 功能,必须加这个依赖。
三、核心概念(新手友好版)
别被术语吓到,其实就三个关键角色:
| 角色 | 作用 | 类比 |
|---|---|---|
UserDetails |
存储用户信息(用户名、密码、权限等) | 员工档案 |
UserDetailsService |
根据用户名查用户(比如查数据库) | HR 查花名册 |
PasswordEncoder |
密码加密器(明文密码不安全!) | 密码保险柜 |
🔑 重点理解:
Spring Security 默认会找一个叫UserDetailsService的 Bean,你只要提供它,框架就知道“怎么查用户”。
四、实战:5 步搭建登录系统
第 1 步:创建用户实体(模拟数据库)
我们先不用真数据库,用内存模拟(适合学习)。
// src/main/java/com/example/demo/model/User.java
public class User {
private String username;
private String password;
private List<String> roles;
// 构造函数、getter/setter 省略
}
第 2 步:实现 UserDetailsService
// src/main/java/com/example/demo/service/CustomUserDetailsService.java
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 模拟从数据库查用户(实际项目这里查 DB)
if ("alice".equals(username)) {
return User.builder()
.username("alice")
.password(passwordEncoder().encode("123456")) // 密码必须加密!
.roles("USER")
.build();
}
throw new UsernameNotFoundException("用户不存在");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // 推荐用 BCrypt
}
}
⚠️ 重要提醒:
永远不要存明文密码!BCryptPasswordEncoder会自动加盐加密,每次加密结果都不同,但能正确验证。
第 3 步:配置 Security(核心!)
// src/main/java/com/example/demo/config/SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login", "/css/**", "/js/**").permitAll() // 登录页和静态资源放行
.anyRequest().authenticated() // 其他所有请求都要登录
)
.formLogin(form -> form
.loginPage("/login") // 自定义登录页路径
.defaultSuccessUrl("/home") // 登录成功跳转
.permitAll()
)
.logout(logout -> logout
.logoutSuccessUrl("/login?logout")
.permitAll()
);
return http.build();
}
}
🧠 架构思考:
这段代码其实是 声明式安全策略——你告诉框架“哪些路径公开,哪些要登录”,而不是手写 if-else 判断。这就是 Spring Security 的优雅之处!
第 4 步:写前端页面(超简单)
<!-- src/main/resources/templates/login.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>登录</td>
</head>
<body>
<h2>用户登录</h2>
<!-- 错误提示 -->
<div th:if="${param.error}">
用户名或密码错误!
</div>
<!-- 退出提示 -->
<div th:if="${param.logout}">
您已安全退出!
</div>
<form th:action="@{/login}" method="post">
<div>
<label>用户名:</label>
<input type="text" name="username" required />
</div>
<div>
<label>密码:</label>
<input type="password" name="password" required />
</div>
<button type="submit">登录</button>
</form>
</body>
</html>
<!-- src/main/resources/templates/home.html -->
<h1>欢迎回家!</h1>
<p>当前用户:<span sec:authentication="name"></span></p>
<a href="/logout">退出登录</a>
💡 注意:
表单字段名必须是username和password,这是 Spring Security 默认的参数名(可改,但新手别动)。
第 5 步:启动 & 测试
- 运行 Spring Boot 应用
- 访问
http://localhost:8080/home - 自动跳转到
/login - 输入:
- 用户名:
alice - 密码:
123456
- 用户名:
- 登录成功!看到欢迎页
五、新手常见问题解答(Q&A)
Q1:为什么我访问任何页面都跳到 /login?
A:因为你没放行静态资源或登录页!检查 SecurityConfig 中是否用了 .permitAll()。
Q2:密码明明对,却一直提示错误?
A:大概率是密码没加密!确保 UserDetailsService 里用 passwordEncoder().encode() 处理过密码。
Q3:能不能用手机号/邮箱登录,而不是用户名?
A:可以!你需要自定义 AuthenticationProvider,但新手先用默认方案,别一上来就改底层。
Q4:和前端(Vue/React)怎么配合?
A:本文用 Thymeleaf 是为了简化。真实项目中,后端提供 /api/login 接口,前端用 Axios 调用即可。安全逻辑仍在后端!
Q5:简历上怎么写这个项目?
A:可以这样写:
“基于 Spring Security 实现 RBAC 权限模型,支持多角色动态授权,密码采用 BCrypt 加密存储,防止暴力破解。”
六、学习建议 & 下一步
🚫 避坑指南(血泪经验!)
- 不要一上来就集成 JWT!先掌握 Session 认证。
- 不要手写权限拦截逻辑!用
@PreAuthorize("hasRole('ADMIN')")注解。 - 不要忽略 CSRF!表单提交默认开启 CSRF 保护,Ajax 请求需特殊处理。
🔜 下一步学什么?
| 方向 | 推荐学习内容 |
|---|---|
| 深度 | 自定义 AuthenticationProvider、密码策略、记住我功能 |
| 广度 | OAuth2(微信/Google 登录)、JWT(前后端分离) |
| 扩展 | 结合 Redis 存 Session、集成 Swagger 文档权限 |
💬 最后说两句
我知道,很多同学学 Security 是因为 算法题刷不动、Go 语言还没入门,想先搞个后端项目充实简历。这完全没问题!安全模块是后端项目的“高光功能”,做好了面试能聊 10 分钟。
我当初第一份工作面试,就靠一个带权限控制的博客系统拿到了 offer。技术不在于多深,而在于能跑通、能讲清、能避坑。
动手吧!
把今天这个小项目跑起来,然后试着加个“只有 admin 能访问的后台页”。遇到问题?欢迎在评论区留言(B 站同名 UP 主有视频版讲解)!
作者:阿哲 | 大厂后端工程师 & 技术 UP 主
原创不易,转载请注明出处

评论 0