Search code examples
springspring-bootspring-securityoauth-2.0

OAuth2 server with spring boot: accessing token endpoint returns "404 NOT FOUND" for the token endpoint


My spring boot project uses dependency implementation("org.springframework.security:spring-security-oauth2-authorization-server") to develop an OAuth2 complient authorization server.

My beans configuration is this:

@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);
  }

}

When I'm running the application, I try to verify the "authorization code" grant type to get an access token. Following is what I did:

Firstly, I access the "authorize" endpoint in order to get authorization code:

I open browser and access url http://localhost:9000/oauth2/authorize?response_type=code&client_id=client&scope=openid&redirect_uri=https://spring.io

My browser shows Spring provided user login page, I submitted username and password, after which my browser is successfully redirected to https://spring.io?code=wPy5G_Fzm6HCXRwX8vLV2aBtiPC9y9nc2z0GTe8n5opT_e2GpQO40rcMCleynII4fyx6kwHtWbGnlLXOH977oCwLgzOp3kqkOyJNQXl8YJ8-VwrU5erOw-HUM34-jOda. As you can see, the "authorization code" is also appended to the redirect uri.

Then, I copy the authorization code & access the "token" endpoint:

I open Postman, run GET request against the token endpoint /oauth2/token provided also the above authorization code:

http://localhost:9000/oauth2/token?client_id=client&redirect_uri=https://spring.io&grant_type=authorization_code&code=wPy5G_Fzm6HCXRwX8vLV2aBtiPC9y9nc2z0GTe8n5opT_e2GpQO40rcMCleynII4fyx6kwHtWbGnlLXOH977oCwLgzOp3kqkOyJNQXl8YJ8-VwrU5erOw-HUM34-jOda,

but I get response 404 NOT FOUND for the token endpoint "/oauth2/token", here is the screenshot:

enter image description here

I then tried the following way to debug the above 404 issue & check whether token endpoint is really not available:

I firstly verify the authorization endpoint /oauth2/authorize by accessing it without any parameter, I expect a 400 bad request error instead of 404 Not found. The result is as expected:

enter image description here

It means the /oauth2/authorize endpoint is indeed working!

Then, I expect the token endpoint /oauth2/token also returns 400 bad request when no parameter, but it still responses 404 NOT FOUND:

enter image description here

This proves to me that the token endpoint /oauth2/token is not available...I wonder why?

Then, I check from the .well-known endpoint, interestingly, it tells me the token endpoint /oauth2/token should be available:

enter image description here

This makes me very confused now, why I get 404 NOT FOUND for /oauth2/token endpoint when accessing it?


Solution

  • The token endpoint /oauth2/token is POST http Method not GET.

    enter image description here