You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security OAuth2客户端凭证流token接口返回404问题

问题根因

调用/oauth2/token返回404是三个配置缺失导致的:

  1. 未显式配置授权服务器专属的Security过滤器链,OAuth2端点没有被注册到服务路由中
  2. 客户端密钥未加{noop}前缀,默认密码校验规则下明文密钥无法通过客户端认证
  3. 请求地址中的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_credentials
    • scope:按需填写,例如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. 全链路验证

  1. 启动授权服务器,按照第二步的参数调用token接口,拿到有效access_token
  2. 启动资源服务器,发送GET请求到http://127.0.0.1:8090/api/messages,请求头添加:
    Authorization: Bearer 你拿到的access_token
    
  3. 正常返回200状态码和接口内容即为配置成功;如果token无效、过期或缺少对应scope,会返回401/403状态码。

内容的提问来源于stack exchange,提问作者skyho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 19:45:56