I'm working on an OAuth2 authorization server using Spring Authorization Server. I need to support the client credentials flow and I like the client to send the client id and secret in the JSON request body of the POST request.
My configuration is pretty straightforward. It's basically all default settings with a custom RegisteredClientRepository
:
@Configuration
@Import(OAuth2AuthorizationServerConfiguration.class)
public class AuthorizationServerConfig {
@Bean
@Primary
public RegisteredClientRepository registeredClientRepository(UserRepository repository) {
return repository;
}
}
The findByClientId
method in UserRepository looks like this:
@Repository
@RequiredArgsConstructor
public class UserRepository implements RegisteredClientRepository {
private final UserDao UserDao;
@Override
public RegisteredClient findByClientId(String clientId) {
return userDao.findByClientId(clientId)
.map(this::toRegisteredClient)
.orElse(null);
}
private RegisteredClient toRegisteredClient(User user) {
return RegisteredClient.withId(String.valueOf(user.getId()))
.clientName(user.getName())
.clientId(user.getClientId())
.clientSecret(user.getClientSecret())
.clientAuthenticationMethod(CLIENT_SECRET_BASIC)
.clientAuthenticationMethod(CLIENT_SECRET_POST)
.authorizationGrantType(CLIENT_CREDENTIALS)
.scope("TEST")
.clientSettings(
ClientSettings.builder().requireAuthorizationConsent(false).build()
)
.build();
}
}
Assume the client id to be user
and the secret to be password
.
Requesting a token using basic authentication works:
curl -X POST --header "Authorization: Basic dXNlcjpwYXNzd29yZA==" http://localhost:8080/oauth2/token\?grant_type\=client_credentials
I can also request a token using request URI parameters:
curl -X POST http://localhost:8080/oauth2/token\?grant_type\=client_credentials\&client_id\=user\&client_secret\=password
But when I try to send the credentials as JSON in the request body like this I get an HTTP 401 error:
curl --header "Content-Type: application/json" -d '{"grant_type": "client_credentials", "client_id": "user", "client_secret": "password"}' http://localhost:8080/oauth2/token
How do I make this to work?
Also, why does the Spring Authorization Server support sending client credentials as request URI parameters? Section 2.3 of the OAuth 2.1 specifications specifically state that request URI parameters must not be used as this is deemed insecure.