🎏:你只管努力,剩下的交给时间
🏠 :小破站
从0到1掌握 Spring Security(第一篇):零配置也能跑!🔐🚀
摘要
- 本文是“从0到1掌握 Spring Security”的第1篇,目标是用最小成本跑通一个带登录保护的 Spring Boot 应用。
- 通过引入依赖即可获得默认的安全保护,启动时会在控制台打印临时密码:Using generated security password: …。
- 文章将带你理解这条日志的来源(Spring Boot 自动配置),并演示如何用两种方式自定义用户名和密码。
- 风格通俗易懂,配合图标与强调标签,适合初学者快速入门。
一、为什么是 Spring Security?🧭
- 安全就是:认证(你是谁)+ 授权(你能做什么)。
- Spring Security 是 Spring 家族的“安全管家”,内置过滤器链 + 认证授权模型 + CSRF/会话/密码加密等一整套能力。
- 对新手非常友好的一点是:默认即安全(Secure by default),只要引 starter 就会保护你的应用,不配置也能跑,甚至还会自动给你一个临时密码!
二、开箱即用:Spring Boot 如何让它“自己动起来”🧩
Spring Boot 做了两件超省心的事:
- 自动配置:你不写 SecurityFilterChain / UserDetailsService 等 Bean 时,Boot 会给你准备“默认配置”。
- 默认策略:所有请求都需要登录、默认提供登录页、默认用户名 user + 随机密码(启动时在控制台打印)。
这意味着:只要引依赖、写个最小的控制器和页面,你就能完整跑通登录流程。很适合从0开始学习!😎
三、先看我们的最小可用项目(acowbo)📦
我们已经准备好了一个极简项目:Spring Boot 3 + Spring Security 6 + Thymeleaf,包名前缀是 acowbo。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
@GetMapping("/")
public String home() { return "home"; }
@GetMapping("/dashboard")
public String dashboard(Model model, Principal principal) {
if (principal != null) {
model.addAttribute("username", principal.getName());
}
return "dashboard";
}
- Thymeleaf 页面:home.html、dashboard.html。
- 应用配置 application.yml 里目前包含了 spring.security.user(为了教学,我们先把它注释掉,这样才能看到“随机密码”的提示,后面再加回来做自定义演示):
# spring:
# security:
# user:
# name: user
# password: acowbo123
# roles: USER
四、运行!先不配置用户,观察“随机密码”🔎
- 临时注释掉 application.yml 中 spring.security.user 配置(如上所示)。
- 启动项目:
- 注意控制台,会出现类似这一行(每次值不同):
Using generated security password: 3160e790-0ee7-4561-bfca-41edb701dd88
访问 http://localhost:18080
- 未登录将跳到默认的登录页(或你自定义的 login.html,后续文章会教你绑定);
- 输入 user + 上面的随机密码 登录;
- 登录成功后,访问 dashboard 或首页时会显示“欢迎,用户名”等内容。✅
这一步的意义是:你啥都没配,Spring Security 已经保护你的应用,并提供了一个可用的临时账户。这对入门极其友好,也让生产环境默认更安全(不是裸奔)。
五、这串“随机密码”是怎么来的?源码位置在哪里?🧠
别慌,我们不是要你从今天开始啃源码。这里只给你一个清晰、可复述的定位思路,让你知道它“来自哪里”。
- 关键词:Spring Boot 自动配置
- 包位置(大方向):org.springframework.boot.autoconfigure.security.servlet
- 核心类:UserDetailsServiceAutoConfiguration
- 它会读取 SecurityProperties(也就是 spring.security.* 配置)
- 在你没有声明自有 UserDetailsService 且 没有配置 spring.security.user.password 的情况下:
- 它会创建一个内存用户(默认用户名 user)
- 生成一个随机密码(UUID)
- 通过日志输出你刚才看到的那句:Using generated security password: …
换句话说:随机密码来自 Spring Boot 的“自动配置模块”,而不是 Spring Security 核心库本身。只要你不自己接管,它就会“兜底”给你一个可登录的账户。这就是 Boot 的开箱即用理念。
六、现在来“自定义用户名密码”🛠️
看过默认行为,接下来我们把用户名/密码改成自己的。我们推荐两种方式:
方式 A:直接在 application.yml 里配置(最简单,适合教学/演示)
把之前注释掉的配置加回来(或新写上),例如:
spring:
security:
user:
name: user
password: acowbo123
roles: USER
重启应用:
- 这时控制台不会再打印“Using generated security password”
- 直接用 user / acowbo123 登录即可
优点:快、简单、直观
缺点:密码明文、不适合生产、扩展性有限(不能灵活控制过滤器链、密码加密、多用户、多角色)
方式 B:通过 Bean 进行更灵活的配置(适合进阶与生产)
思路概要(留作后续篇章的动手实战):
- 定义 PasswordEncoder(如 BCryptPasswordEncoder),让密码不以明文存储
- 定义 InMemoryUserDetailsManager 或从数据库加载的 UserDetailsService,加入多个用户和角色
- 定义 SecurityFilterChain,自定义哪些路径放行、登录页、登出、CSRF、异常处理等
对比方式 A:
- 方式 B 更强更灵活,更贴近真实项目,但也需要更多知识(过滤器链、认证流程、授权规则…)
- 我们会在下一篇循序渐进地讲,手把手把你的 login.html 和过滤器链“绑起来”,变成你自己的登录表单。🧪
七、运行过程的“脑图版”理解图 🗺️
- 你引入 starter-security → 自动配置生效
- 没有自己的用户配置?→ 生成默认用户(user + 随机密码)
- 启动时日志输出 → Using generated security password: …
- 所有请求默认需要登录 → 访问 / 会被要求认证
- 登录成功 → 进入你的页面(home/dashboard)
- 想自定义?→ yml 配置 或 Bean 配置 两条路线
一句话总结:默认即安全,渐进式收束复杂度。
八、常见小问题(第一篇就先解决到这)❓
- 随机密码每次都变,能固定吗?
→ 可以,用 yml 配置 spring.security.user.password 即可。
- 控制台没看到“Using generated security password”?
→ 检查是否已经配置了 spring.security.user.password 或者自己提供了 UserDetailsService/PasswordEncoder 等。
九、今天的收获与下一步 ✅
今天你已经完成了:
- 从0启动一个带安全保护的 Spring Boot 应用(不写任何 Security 配置)
- 看懂随机密码的来源(Spring Boot 自动配置里的 UserDetailsServiceAutoConfiguration)
- 用两种方式自定义用户名/密码(yml 快速方式 + Bean 进阶方式的思路)
接下来我们会在第2篇里动手做:
- 自定义 SecurityFilterChain,绑定我们自己的 login.html
- 引入 PasswordEncoder(如 BCrypt),实现加密密码
- 基于角色/权限做最小可行的授权策略
- 讲清楚请求是如何穿越过滤器链的(带图示和简单调试)
如果你愿意,我可以把当前项目中 application.yml 的 spring.security.user 暂时注释掉,帮你启动一次并抓取“Using generated security password”完整日志,然后再改回自定义密码,做一个对比展示。想看现场版就告诉我!🔥
——
小结关键句(背下来超有用):
只引入 Spring Security 依赖,Spring Boot 就会通过自动配置提供 默认用户(user + 随机密码)和基础认证流程;当你在 yml 或 Bean 层主动配置后,你的配置将覆盖默认行为。这就是“默认即安全,按需增强”。