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
The client admin-client exists in the database with secret secret (stored plaintext).
Tried both CLIENT_SECRET_BASIC (via header) and CLIENT_SECRET_POST (via body) – same error.
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?
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.