Spring Boot安全配置全解析
以下内容是 Spring Boot 官方文档中关于安全(Security)配置的章节,主要描述了 Spring Boot 如何与 Spring Security 集成,并自动为你的应用程序提供默认的安全保护。下面我们来一步步地、通俗易懂地解释这段文档的核心含义和关键点。
🧩 一、整体概览
当你的项目里引入了 spring-boot-starter-security
依赖后:
✅ Spring Boot 会自动为你开启安全机制
🔐 所有 Web 接口默认都被保护起来(需要登录才能访问)
这是“约定优于配置”的体现 —— 不用写代码,就获得了基础安全能力。
🔐 二、默认行为详解
1. 默认用户
- Spring Boot 自动生成一个内存中的用户:
- 用户名:
user
- 密码:随机生成,启动时打印在日志中(INFO 级别)
Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
- 用户名:
- ⚠️ 注意:如果你把日志级别调得太高(比如只显示 WARN),可能看不到这个密码!要确保
org.springframework.boot.autoconfigure.security
的日志级别是 INFO。
✅ 自定义用户名/密码
spring.security.user.name=admin
spring.security.user.password=123456
2. 默认安全规则(适用于 MVC 和 WebFlux 应用)
功能 | 描述 |
---|---|
UserDetailsService | 内存存储,包含上面那个默认用户 |
登录方式 | 根据请求头 Accept 决定:- 浏览器访问 → 表单登录(formLogin) - API 工具如 Postman → HTTP Basic 认证 |
权限范围 | 整个应用的所有路径都受保护(包括 /actuator/** 如果引入了 Actuator) |
认证事件发布 | 提供了一个 DefaultAuthenticationEventPublisher ,可以监听登录成功/失败等事件 |
🛠️ 三、如何自定义安全策略?
3.1 对于 Spring MVC 应用(基于 Servlet)
方法一:关闭默认安全配置
添加一个 WebSecurityConfigurerAdapter
子类即可覆盖默认行为:
@Configuration
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest().authenticated().and().formLogin();}
}
💡 添加这个类之后,Spring Boot 的默认 web 安全配置不再生效(但 UserDetailsService 的配置仍然有效)
方法二:完全禁用默认用户配置
如果你想自己管理用户认证逻辑,可以提供以下任意 Bean:
UserDetailsService
AuthenticationProvider
AuthenticationManager
这样连默认的 user
用户也不会创建了。
方便工具类:
Spring Boot 提供两个工具帮助你轻松设置 Actuator 和静态资源权限:
EndpointRequest.toAnyEndpoint()
:匹配所有监控端点PathRequest.toStaticResources().atCommonLocations()
:匹配常见静态资源目录(如/css
,/js
,/images
等)
示例:
@Override
protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll().requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ADMIN").anyRequest().authenticated().and().formLogin();
}
3.2 对于 WebFlux 应用(响应式编程模型)
类似地,使用 SecurityWebFilterChain
而不是 HttpSecurity
。
示例:
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {return http.authorizeExchange().matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll().pathMatchers("/foo", "/bar").authenticated().and().formLogin().build();
}
❗ 关闭默认安全的方式是定义一个
WebFilterChainProxy
类型的 bean。
🔑 四、OAuth2 支持(第三方登录)
Spring Boot 支持 OAuth2 客户端、资源服务器等功能。
4.1 OAuth2 客户端(Client)
用于实现“使用 GitHub / Google / 微信等账号登录”
步骤:
-
引入依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency>
-
配置 application.yml:
spring:security:oauth2:client:registration:my-google:client-id: your-client-idclient-secret: your-client-secretprovider: googlescope: profile,emailredirect-uri: http://localhost:8080/login/oauth2/code/my-googleprovider:google:authorization-uri: https://accounts.google.com/o/oauth2/authtoken-uri: https://oauth2.googleapis.com/tokenuser-info-uri: https://www.googleapis.com/oauth2/v3/userinfo
✅ 更简单的方法:直接使用预设提供商(google, github, facebook, okta)
只需注册名为
自定义回调地址
默认回调路径是 /login/oauth2/code/*
,如果想改成 /custom-callback
,需要手动配置:
http.oauth2Login().redirectionEndpoint().baseUri("/custom-callback");
OAuth2AuthorizedClientService
- 默认使用内存存储授权信息(
InMemoryOAuth2AuthorizedClientService
) - ❌ 不适合生产环境!建议换成数据库支持的
JdbcOAuth2AuthorizedClientService
4.2 OAuth2 资源服务器(Resource Server)
用来验证 JWT 或 Opaque Token(即:别人带着 token 请求你,你要验证它是否合法)
场景:接收 JWT 并校验签名
方式一:通过 JWK Set URI(推荐)
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://example.com/oauth2/default/v1/keys
方式二:通过 Issuer URI(OIDC 发现机制)
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/
自动从
.well-known/openid-configuration
获取元数据
方式三:指定公钥文件(PEM 格式)
spring.security.oauth2.resourceserver.jwt.public-key-location=classpath:my-public-key.pem
使用 Opaque Token(不透明令牌)
适用于非 JWT 的 token,通过远程服务验证有效性:
spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://auth-server/check-token
spring.security.oauth2.resourceserver.opaquetoken.client-id=my-client
spring.security.oauth2.resourceserver.opaquetoken.client-secret=my-secret
✅ 也可以自定义
OpaqueTokenIntrospector
或ReactiveOpaqueTokenIntrospector
4.3 没有 Authorization Server?
⚠️ 文档明确指出:
Spring Security 当前不支持构建 OAuth2 授权服务器(Authorization Server)
但你可以使用旧项目:
spring-security-oauth2-autoconfigure
模块- 或等待未来 Spring Security 原生支持(目前还在开发中)
🛡️ 五、SAML 2.0 支持(企业级单点登录)
SAML 是另一种企业常用的 SSO 协议(常用于公司内部系统对接 AD/LDAP)。
启用条件:
<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-saml2-service-provider</artifactId>
</dependency>
配置示例:
spring.security.saml2.relyingparty.registration.my-saml:signing:credentials:- private-key-location: classpath:saml/key.pemcertificate-location: classpath:saml/cert.crtidentityprovider:entity-id: https://idp.example.comsso-url: https://idp.example.com/ssoverification:credentials:- certificate-location: classpath:saml/idp-cert.crt
这表示你的应用作为 服务提供方(SP),信任某个 IDP(身份提供者)
📊 六、Actuator 安全(运维接口保护)
Actuator 提供了很多监控接口,如 /health
, /metrics
, /env
等。
默认策略:
/health
和/info
:公开可访问- 其他所有 endpoint(如
/shutdown
,/loggers
):默认关闭 + 受保护
开启某些端点:
management.endpoints.web.exposure.include=health,info,metrics,loggers
⚠️ 警告:暴露敏感端点前一定要评估风险!例如
/env
包含配置信息,应配合 Spring Security 限制访问。
CSRF 保护
- Spring Security 默认开启 CSRF 防护
- 所以像
/actuator/shutdown
这种 POST 请求,在浏览器中会因缺少 CSRF Token 而被拒绝(返回 403)
解决方案(二选一):
- 生产推荐:保留 CSRF,前端正确发送
_csrf
token - 测试/非浏览器场景:关闭 CSRF
http.csrf().disable();
✅ 总结:核心要点一览表
主题 | 关键结论 |
---|---|
默认安全 | 只要引入 Spring Security,所有接口受保护 |
默认用户 | 用户名 user ,密码随机生成并输出到日志 |
自定义 | 添加 WebSecurityConfigurerAdapter 可覆盖默认配置 |
OAuth2 Client | 支持 Google/GitHub/Facebook/Okta 快速集成 |
OAuth2 Resource Server | 支持 JWT 和 Opaque Token 验证 |
OAuth2 Auth Server | ❌ Spring Security 尚未支持,可用 legacy 模块 |
SAML 2.0 | 支持作为 Relying Party 实现企业 SSO |
Actuator | 敏感端点默认关闭,需显式开启并注意权限控制 |
CSRF | 默认开启,POST/PUT/DELETE 请求需处理 |
📚 建议学习路径
- 先理解 Spring Security 基础概念(Filter Chain, Authentication, Authorization)
- 学会用
WebSecurityConfigurerAdapter
或SecurityWebFilterChain
控制权限 - 实践 OAuth2 登录(如 GitHub 登录)
- 配置资源服务器验证 JWT(结合 Keycloak / Auth0 / Okta)
- 生产部署时考虑持久化
OAuth2AuthorizedClientService
- 审查 Actuator 暴露的端点安全性
如果你想进一步深入某一部分(比如“如何实现 GitHub 登录”或“JWT 如何解析用户信息”),欢迎继续提问!我可以给出完整代码示例。