Spring Security零基础入门:5分钟搭起你的第一个安全系统
大家好,我是工作5年的后端开发工程师。记得我当初学Spring Security的时候,光是看文档就花了整整两天,配置完还各种报错——登录页跳转不了、密码加密方式不对、权限死活不生效……真的头大。
所以今天,我想用最简单的方式,带你快速上手Spring Security。不用懂OAuth2,不用会JWT,只要你会写Hello World,就能跟着这篇教程跑通一个带用户名密码登录的安全系统。
这篇文章就是一份“防踩坑”指南,专为Java零基础或刚接触安全认证的新手准备。我们一步步来,保证你学得明白、跑得起来!
为什么需要Spring Security?
想象一下:你做了一个后台管理系统,任何人都能直接访问 /admin 页面删数据?这显然不行。
Spring Security 就是给你的Java应用加“门锁”的工具。
它能帮你实现:
- 用户登录(谁可以进来?)
- 权限控制(进来后能干什么?)
- 防止攻击(比如暴力破解、跨站请求伪造等)
而这一切,Spring Boot + Spring Security 几乎“开箱即用”。
环境准备:5分钟搭好开发环境
✅ 前提:你已经安装了 JDK 8+ 和 Maven(或 Gradle)
第一步:创建Spring Boot项目
你可以用 https://start.spring.io 快速生成项目。
依赖选择:
- Spring Web
- Spring Security
- Thymeleaf(用于简单页面展示,可选但推荐)
或者直接在 pom.xml 中添加:
<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>
</dependencies>
第二步:确认主启动类
确保你有类似这样的主类:
@SpringBootApplication
public class SecurityDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SecurityDemoApplication.class, args);
}
}
搞定!环境就绪。
核心概念:3个词搞懂Spring Security
别被术语吓到,其实就三件事:
| 概念 | 通俗解释 | 对应代码角色 |
|---|---|---|
| 认证(Authentication) | “你是谁?” —— 登录验证身份 | UserDetails, UserDetailsService |
| 授权(Authorization) | “你能干啥?” —— 控制访问权限 | @PreAuthorize, hasRole() |
| 资源(Resource) | 被保护的东西,比如 /api/users、/admin 页面 |
URL路径、方法、数据库记录等 |
💡 重点理解“资源”:在安全系统中,任何需要保护的内容都叫“资源”。比如:
- 一个网页(
/dashboard)- 一个API接口(
/api/deleteUser)- 甚至是一条数据库记录(“只有作者能编辑自己的文章”)
我们今天的目标:保护几个资源,只让登录用户访问。
实战:手把手搭建一个安全登录系统
我们将完成以下功能:
- 访问
/显示欢迎页(无需登录) - 访问
/user需要登录 - 提供一个简单的登录页
- 使用内存中的用户账号(用户名/密码)
第一步:创建首页和用户页
在 src/main/resources/templates 下创建两个Thymeleaf页面:
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>首页</title></head>
<body>
<h1>欢迎来到首页!</h1>
<p>这是公开资源,所有人都能看。</p>
<a th:href="@{/user}">去用户页面(需登录)</a>
</body>
</html>
user.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>用户页</title></head>
<body>
<h1>你好,[[${#httpServletRequest.remoteUser}]]!</h1>
<p>这是受保护的资源,只有登录用户才能看到。</p>
<form th:action="@{/logout}" method="post">
<button type="submit">退出登录</button>
</form>
</body>
</html>
第二步:编写控制器
@Controller
public class PageController {
@GetMapping("/")
public String home() {
return "index"; // 返回 templates/index.html
}
@GetMapping("/user")
public String userPage() {
return "user";
}
}
第三步:配置Spring Security(关键!)
创建配置类:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/login").permitAll() // 允许所有人访问首页和登录页
.anyRequest().authenticated() // 其他所有请求必须登录
)
.formLogin(form -> form
.loginPage("/login") // 自定义登录页(Spring Security会自动生成)
.permitAll()
)
.logout(logout -> logout
.permitAll()
);
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
// 创建一个内存中的用户:用户名 user,密码 123456
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder().encode("123456"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // 密码必须加密存储!
}
}
🔒 重要提醒:Spring Security 强制要求密码加密!如果你直接写
.password("123456"),启动会报错。所以我们用BCryptPasswordEncoder加密。
第四步:运行并测试
- 启动应用(默认端口8080)
- 访问
http://localhost:8080→ 看到首页 - 点击链接进入
/user→ 自动跳转到/login - 输入用户名
user,密码123456→ 成功进入用户页 - 点击“退出登录” → 回到登录页
🎉 恭喜!你已经搭建了一个完整的认证系统!
新手常见问题 & 解决方案
❓ 问题1:为什么登录页是Spring Security自动生成的?我能自定义吗?
答:当然可以!上面我们用了 .loginPage("/login"),但没提供 /login 的页面,所以Spring Security自动渲染了一个默认登录页。
如果你想自定义,只需加一个控制器:
@GetMapping("/login")
public String login() {
return "login"; // 你需要自己写 login.html
}
然后在 login.html 中包含表单(注意字段名必须是 username 和 password):
<form th:action="@{/login}" method="post">
<input type="text" name="username" placeholder="用户名" />
<input type="password" name="password" placeholder="密码" />
<button type="submit">登录</button>
</form>
❓ 问题2:密码明文写在代码里不安全,怎么办?
答:这只是教学示例!实际项目中,用户数据应来自数据库。
你可以这样改:
- 创建
UserRepository查询数据库 - 实现
UserDetailsService接口,从DB加载用户 - 依然使用
BCryptPasswordEncoder加密比对
后续我会专门写一篇《Spring Security + 数据库实战》。
❓ 问题3:如何区分“普通用户”和“管理员”?
答:用角色(Role)!比如:
User admin = User.builder()
.username("admin")
.password(encoder.encode("admin123"))
.roles("ADMIN") // 注意:这里会自动加前缀 ROLE_
.build();
然后在配置中限制:
.requestMatchers("/admin/**").hasRole("ADMIN") // 只有ROLE_ADMIN能访问
💡 Spring Security 会自动给角色加
ROLE_前缀,所以.roles("ADMIN")实际存储为ROLE_ADMIN。
学习建议:下一步怎么走?
你现在已经掌握了Spring Security的基础骨架。接下来可以按这个路径深入:
连接真实数据库
把InMemoryUserDetailsManager换成从MySQL/PostgreSQL读取用户。理解过滤器链(Filter Chain)
Spring Security底层是一堆过滤器,了解它们有助于调试。尝试前后端分离方案
用 JWT 或 Session + Cookie 实现 API 认证(适合Vue/React前端)。学习方法级安全
用@PreAuthorize("hasRole('ADMIN')")保护Service方法。集成第三方登录
如微信、GitHub、Google登录(需要用到OAuth2)。
📌 避坑指南:
- 不要关闭CSRF防护(除非做纯API且用Token)
- 永远不要明文存密码
- 开发时可用
.csrf().disable()临时关闭CSRF,但上线务必开启!
结语
这篇【Spring Security基础:快速搭建安全认证系统】的教程,就是我当年希望有人能给我的那份“救命文档”。它没有讲原理堆砌,而是聚焦于“让你立刻跑起来”。
记住:安全不是功能,而是基础设施。哪怕你的项目再小,也应该从第一天就考虑“谁可以访问什么资源”。
现在,打开你的IDE,照着代码敲一遍吧!遇到问题,欢迎留言讨论。下期我们讲《Spring Security + MySQL:从内存用户到数据库认证》。
祝你编码愉快,安全无忧!

评论 0