0
votes

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.