Spring Boot集成OAuth2资源服务器的核心是让应用仅作为“守门人”验证JWT令牌,不参与登录与发Token;它依赖外部授权服务器签发JWT,通过JWK Set校验签名、有效期及scope/roles权限,并基于SecurityFilterChain配置路径级访问控制。

Spring Boot 通过集成 OAuth2 资源服务器实现安全认证,核心是让应用只负责验证令牌、保护接口,不参与登录和发 Token 的过程。它依赖外部授权服务器(如 Keycloak、Auth0 或自建 Spring Authorization Server)签发 JWT,并由资源服务器校验其签名、有效期与权限声明。
明确资源服务器的职责
资源服务器不是认证入口,而是“守门人”:它不处理用户名密码,也不重定向用户去登录页;它只做三件事——解析请求头中的 Bearer Token、验证 JWT 是否合法有效、检查 token 中的 scope/roles 是否满足接口所需权限。
- Token 必须是 JWT 格式(推荐),便于无状态校验
- 验证依据通常是授权服务器公开的 JWK Set(
jwk-set-uri)或本地公钥 - 权限控制基于
scope(如read:order)或roles(如ROLE_ADMIN)
引入关键依赖并启用资源服务
在 pom.xml 中添加:
-
spring-boot-starter-oauth2-resource-server(必需) -
spring-boot-starter-security(自动引入) - 若需细粒度权限表达式,可加
spring-boot-starter-web
无需额外注解,只要依赖存在且配置正确,Spring Security 就会自动启用资源服务器模式。
立即学习“Java免费学习笔记(深入)”;
配置授权服务器元数据地址
在 application.yml 中指定 JWT 公钥来源:
spring:
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: https://auth.example.com/realms/demo/protocol/openid-connect/certs
该地址返回标准的 JWK Set JSON,Spring Security 会自动缓存并用于验证所有传入的 JWT。若用对称密钥(不推荐生产),可用 secret 配置,但仅限测试。
定义接口访问规则
通过 SecurityFilterChain Bean 声明保护策略:
- 匹配路径如
/api/**的请求必须携带有效 token - 按 scope 控制:
hasAuthority('SCOPE_read:product') - 按角色控制:
hasRole('ADMIN')(注意自动加上ROLE_前缀) - 开放健康端点:
requestMatchers("/actuator/health").permitAll()
示例配置:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authz -> authz
.requestMatchers("/actuator/**").permitAll()
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/product/**").hasAuthority("SCOPE_read:product")
.anyRequest().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
验证与调试技巧
启动后,用 curl 测试:
curl -H "Authorization: Bearer eyJraWQiOiIxMjM0NTYiLCJhbGciOiJSUzI1NiJ9..." \ http://localhost:8080/api/product/list
常见失败原因:
- 401 Unauthorized:token 缺失、格式错误(非 Bearer)、过期或签名无效
- 403 Forbidden:token 有效但缺少对应 scope 或 role
- 日志开启
logging.level.org.springframework.security=DEBUG可查看 JWT 解析细节


















