I have setup a simple Spring Authorization Server using the example provided in the Spring Authorization Server repo.
I am using OIDC Debugger to test it out. I am able to get the form login page. I enter my user ID and password, and I'm successfully able to get the Authorization code. The next step is to exchange this code to get the access token (from the /oauth2/token
endpoint). Here is where I get an error.
This is my request to /oauth2/token
curl --location --request POST 'http://localhost:8080/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id=messaging-client' \
--data-urlencode 'client_secret=secret' \
--data-urlencode 'code=ARfoO0m_srZSzi0RJgryvAyxOEmcoOHAZbFVYJlmng71x1CTv7qdCGD3I-DwG8EuBYBdyUGhmZwo5LBmoXyoxxuEuSZwJ7tPjYvQED7OBriRc4uFky5NbtNKuctz1PGt' \
--data-urlencode 'redirct_uri=https%3A%2F%2Foidcdebugger.com%2Fdebug'
When I send this request, I get a 401 Unauthorized
error with the body as follows:
{
"error": "invalid_client"
}
My Security Configuration (just showing the client setup for brevity)
@Bean
public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("messaging-client")
.clientSecret("{noop}secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
.redirectUri("http://127.0.0.1:8080/authorized")
.redirectUri("https://oidcdebugger.com/debug")
.scope(OidcScopes.OPENID)
.scope(OidcScopes.PROFILE)
.scope("message.read")
.scope("message.write")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.build();
// Save registered client in db as if in-memory
JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);
registeredClientRepository.save(registeredClient);
return registeredClientRepository;
}
And, I am also using 1.0.0
version of the Spring Authorization Server dependency.
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>1.0.0</version>
</dependency>
What am I missing?
**Edit: ** I also tried to pass the client ID and secret as a Basic Auth Header (Base64 encoded), as follows:
curl --location --request POST 'http://localhost:8080/oauth2/token' \
--header 'Authorization: Basic bWVzc2FnaW5nLWNsaWVudDpzZWNyZXQ=' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=ARfoO0m_srZSzi0RJgryvAyxOEmcoOHAZbFVYJlmng71x1CTv7qdCGD3I-DwG8EuBYBdyUGhmZwo5LBmoXyoxxuEuSZwJ7tPjYvQED7OBriRc4uFky5NbtNKuctz1PGt' \
--data-urlencode 'redirct_uri=https%3A%2F%2Foidcdebugger.com%2Fdebug'
But this time, I get a 400 Bad Request
error with the following payload
{
"error": "invalid_grant"
}
I found the problem. In the request to /oauth/token, I had made a typo in the redirect_uri
parameter. I fixed that, and it worked.
It was a silly mistake from my side!