Spring Security OAuth2客户端凭证流token接口返回404问题
问题根因
调用/oauth2/token返回404是三个配置缺失导致的:
- 未显式配置授权服务器专属的Security过滤器链,OAuth2端点没有被注册到服务路由中
- 客户端密钥未加
{noop}前缀,默认密码校验规则下明文密钥无法通过客户端认证 - 请求地址中的
auth-server域名未做本地host映射,服务无法被正确寻址
完整全链路配置流程
1. 授权服务器配置修复
首先把授权服务的启动端口设为9000,在application.yml中添加配置:
server: port: 9000
替换你原来的AuthorizationServerConfig配置,补全缺失的Bean:
@Configuration public class AuthorizationServerConfig { // 注册客户端信息 @Bean public RegisteredClientRepository registeredClientRepository() { RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()) .clientId("messaging-client") // 测试用明文密码,加{noop}前缀指定不加密校验 .clientSecret("{noop}secret") .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) .redirectUri("http://127.0.0.1:8080/authorized") .scope("message.read") .scope("message.write") .build(); return new InMemoryRegisteredClientRepository(registeredClient); } // 授权服务器核心安全配置,注册OAuth2端点 @Bean @Order(Ordered.HIGHEST_PRECEDENCE) public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); return http.build(); } // 授权服务器本身的接口安全配置 @Bean public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated()) .formLogin(Customizer.withDefaults()); return http.build(); } // 授权服务器元信息配置,指定签发方地址 @Bean public AuthorizationServerSettings authorizationServerSettings() { return AuthorizationServerSettings.builder() .issuer("http://127.0.0.1:9000") .build(); } }
注意:如果启动报PasswordEncoder相关错误,可额外注册一个NoOpPasswordEncoder的Bean用于测试,生产环境请替换为BCrypt加密。
2. 令牌接口调用方式
用Postman调用时按照以下参数配置,不要直接抄示例的auth-server域名:
- 请求方法:
POST - 请求地址:
http://127.0.0.1:9000/oauth2/token - 认证配置:选择
Basic Auth,用户名填messaging-client,密码填secret - 请求体:选择
x-www-form-urlencoded,添加两个参数:grant_type:固定值client_credentialsscope:按需填写,例如message.read,多个scope用空格分隔
调用成功后会返回包含access_token的JSON响应。
3. 资源服务器搭建
资源服务器可以独立部署,也可以和授权服务器放在同一个项目(建议独立模块测试)。
3.1 添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency>
3.2 基础配置
设置资源服务器端口为8090,在application.yml中添加JWT校验配置:
server: port: 8090 spring: security: oauth2: resourceserver: jwt: # 指向授权服务器地址,自动拉取公钥校验token issuer-uri: http://127.0.0.1:9000
3.3 接口与权限配置
首先在启动类添加注解开启方法级权限校验:
@SpringBootApplication @EnableMethodSecurity public class ResourceServerApplication { public static void main(String[] args) { SpringApplication.run(ResourceServerApplication.class, args); } }
编写测试接口:
@RestController @RequestMapping("/api/messages") public class MessageController { @GetMapping // 要求携带拥有message.read权限的token才能访问 @PreAuthorize("hasAuthority('SCOPE_message.read')") public String getMessage() { return "接口访问成功,这是受保护的消息内容"; } }
4. 全链路验证
- 启动授权服务器,按照第二步的参数调用token接口,拿到有效
access_token - 启动资源服务器,发送GET请求到
http://127.0.0.1:8090/api/messages,请求头添加:Authorization: Bearer 你拿到的access_token - 正常返回200状态码和接口内容即为配置成功;如果token无效、过期或缺少对应scope,会返回401/403状态码。
内容的提问来源于stack exchange,提问作者skyho
相关产品推荐
相关产品推荐

