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

Spring Boot OAuth2授权服务器token端点返回404 NOT FOUND问题

问题描述

我通过Spring Boot引入依赖implementation("org.springframework.security:spring-security-oauth2-authorization-server")开发合规的OAuth2授权服务器,相关Bean配置如下:

@Configuration
public class SecurityConfig {

  @Bean
  @Order(1)
  public SecurityFilterChain asSecurityFilterChain(HttpSecurity http) throws Exception {
    OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);

    http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
        .oidc(Customizer.withDefaults());

    http.exceptionHandling(
        e -> e.authenticationEntryPoint(
            new LoginUrlAuthenticationEntryPoint("/login")
        )
    );

    return http.build();
  }

  @Bean
  @Order(2)
  public SecurityFilterChain appSecurityFilterChain(HttpSecurity http) throws Exception {
    http.formLogin()
        .and()
        .authorizeHttpRequests().anyRequest().authenticated();

    return http.build();
  }

  @Bean
  public UserDetailsService userDetailsService() {
    var u1 = User.withUsername("user")
        .password("password")
        .authorities("read")
        .build();

    return new InMemoryUserDetailsManager(u1);
  }

  @Bean
  public PasswordEncoder passwordEncoder() {
    return NoOpPasswordEncoder.getInstance();
  }

  @Bean
  public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient r1 = RegisteredClient.withId(UUID.randomUUID().toString())
        .clientId("client")
        .clientSecret("secret")
        .scope(OidcScopes.OPENID)
        .scope(OidcScopes.PROFILE)
        .redirectUri("https://spring.io")
        .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
        .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
        .build();

    return new InMemoryRegisteredClientRepository(r1);
  }

  @Bean
  public AuthorizationServerSettings authorizationServerSettings() {
    return AuthorizationServerSettings.builder()
        .build();
  }

  @Bean
  public JWKSource<SecurityContext> jwkSource() throws Exception {
    KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
    kg.initialize(2048);
    KeyPair kp = kg.generateKeyPair();

    RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
    RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();

    RSAKey key = new RSAKey.Builder(publicKey)
        .privateKey(privateKey)
        .keyID(UUID.randomUUID().toString())
        .build();

    JWKSet set = new JWKSet(key);
    return new ImmutableJWKSet(set);
  }

}

运行应用验证授权码授权模式时遇到以下问题:

  • 获取授权码正常:浏览器访问http://localhost:9000/oauth2/authorize?response_type=code&client_id=client&scope=openid&redirect_uri=https://spring.io,登录后成功拿到授权码。
  • 调用/oauth2/token端点获取access token失败:用Postman发送GET请求并携带参数,返回404 NOT FOUND。

调试细节:

  • 无参数访问/oauth2/authorize返回400 Bad Request(符合预期,说明端点存在);
  • 无参数访问/oauth2/token仍返回404;
  • .well-known端点显示/oauth2/token应为可用状态,对此感到困惑,请求解答原因。
问题原因及解决方法

核心原因:请求方法不符合规范

OAuth 2.0规范明确要求/oauth2/token端点必须使用POST请求,而你使用了GET请求,这是导致404的直接原因。

Spring Security OAuth2 Authorization Server对/oauth2/token端点仅开放POST方法,GET请求会被服务器判定为无效请求,进而返回404。

正确的请求方式

  1. 请求方法:必须使用POST
  2. 参数传递:以表单格式(Content-Type: application/x-www-form-urlencoded)传递以下参数:
    • grant_type=authorization_code(固定值,指定授权类型)
    • code=你的授权码(从/oauth2/authorize获取的授权码)
    • redirect_uri=https://spring.io(必须和获取授权码时使用的redirect_uri完全一致)
  3. 客户端认证:由于配置的客户端认证方式是CLIENT_SECRET_BASIC,需要在请求头中添加Basic认证信息:将client:secret进行Base64编码后,放在Authorization: Basic <编码后的字符串>请求头中。

额外注意事项

  • 禁止使用GET请求传递token相关参数,这不仅不符合OAuth规范,还会导致敏感参数暴露在URL中,带来安全风险。
  • 确保redirect_uri与注册客户端时配置的地址完全匹配,否则会返回错误信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:22:36