springspring-bootspring-mvcspring-security

Spring Authorization Server: "invalid_client" Error Despite Correct Client Configuration while requesting registration_endpoint


I'm setting up a Spring Authorization Server (Spring Boot 3.4.1) and encountering an invalid_client error when requesting an access token for a pre-configured client. Here's my setup:

Configration

@Bean  
fun registeredClientRepository(): RegisteredClientRepository {  
    val adminClient = RegisteredClient.withId("admin-client")  
        .clientId("admin-client")  
        .clientSecret("{noop}secret")
        .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)  
        .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)  
        .scope("client.create")  
        .build()  
    return InMemoryRegisteredClientRepository(adminClient)  
}  
    @Bean
    @Order(1)
    @Throws(Exception::class)
    fun authorizationServerSecurityFilterChain(
        http: HttpSecurity, jdbcOperations: JdbcOperations, registeredClientRepository: RegisteredClientRepository
    ): SecurityFilterChain {
        val authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer.authorizationServer()
        http.authorizeHttpRequests { it.requestMatchers("/auth/**").permitAll() }
            .securityMatcher(authorizationServerConfigurer.endpointsMatcher).with(
            authorizationServerConfigurer
        ) { authorizationServer ->
            authorizationServer.registeredClientRepository(registeredClientRepository(jdbcOperations))
                .authorizationService(JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository))
                .authorizationConsentService(
                    JdbcOAuth2AuthorizationConsentService(
                        jdbcOperations,
                        registeredClientRepository
                    )
                ).authorizationServerSettings(endpoints).tokenGenerator(JwtGenerator(NimbusJwtEncoder(jwkSource())))
        }
        return http.build()
    }
POST /auth/oauth2/token  
Content-Type: application/x-www-form-urlencoded  
Authorization: Basic YWRtaW4tY2xpZW50OnNlY3JldA==  # Base64("admin-client:secret")  

grant_type=client_credentials&scope=client.create  

Observations

  1. The client admin-client exists in the database with secret secret (stored plaintext).

  2. Tried both CLIENT_SECRET_BASIC (via header) and CLIENT_SECRET_POST (via body) – same error.

  3. Verified token endpoint URL matches AuthorizationServerSettings.

Error

{  
  "error": "invalid_client"
}  

Question - What could cause Spring Authorization Server to reject valid client credentials despite correct configuration? Are there hidden requirements for client secret storage or authentication method validation?


Solution

  • With a setup in line with Defining Required Components and additional code from OP, this curl-command is working as expected.

    curl -X POST http://localhost:9000/oauth2/token \
            -H "Content-Type: application/x-www-form-urlencoded" \
            -u "admin-client:secret" \
            -d "grant_type=client_credentials" \
            -d "scope=client.create"
    

    I notice that OP is using POST /auth/oauth2/token.

    I can reproduce the invalid_client error when using wrong client secret. In my setup, I have a BCryptPasswordEncoder bean, and I need to encrypt the client secret like shown below:

        @Bean
        public RegisteredClientRepository registeredClientRepository(
                PasswordEncoder passwordEncoder) {
            var registeredClient = RegisteredClient
                    .withId(UUID.randomUUID().toString())
                    .clientId("admin-client")
                    .clientSecret(passwordEncoder.encode("secret"))
                    // remaining setup left out
    

    With .clientSecret("{noop}secret"), I get invalid_client.

    Tested with this auth-server, make your required changes. Please note that the context path is /auth-server for this app.