We are using OAuth2 to get access to a client's access_token to manage some of their Google Locations.
Our implementation is working fine for most of our clients, but there is a user who is receiving the following response when sending an authorization_code request:
{ "error": "invalid_grant", "error_description": "Bad Request"}
I have seen that there are many reasons why we can receive this for refresh_token requests, but why can we receive this for the initial authorization_code request?
Our authorization server URL: https://accounts.google.com/o/oauth2/auth
The token server URL: https://oauth2.googleapis.com/token
We have asked the user to try multiple times, by first removing our application from the authorized accounts, but they still receive the invalid_grant response. The issue is also present when another user of the same company wants to authorize us for the same locations.
Edit for additional details:
We are using spring-social for getting the access token from the authorization code (I know that it is EOL, we are only using a small part of it).
Our own code:
final OAuth2ConnectionFactory<T> connectionFactory = (OAuth2ConnectionFactory<T>) this.connectionFactoryLocator
.getConnectionFactory();
final String callbackUrl = "...";
// This is the failing call
final AccessGrant accessGrant = connectionFactory.getOAuthOperations().exchangeForAccess(code, callbackUrl, null);
The relevant parts of the library call:
public AccessGrant exchangeForAccess(String authorizationCode, String redirectUri, MultiValueMap<String, String> additionalParameters) {
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
if (useParametersForClientAuthentication) {
params.set("client_id", clientId);
params.set("client_secret", clientSecret);
}
params.set("code", authorizationCode);
params.set("redirect_uri", redirectUri);
params.set("grant_type", "authorization_code");
if (additionalParameters != null) {
params.putAll(additionalParameters);
}
return postForAccessGrant(accessTokenUrl, params);
}
protected AccessGrant postForAccessGrant(String accessTokenUrl, MultiValueMap<String, String> parameters) {
Map<String, Object> result = getRestTemplate().postForObject(accessTokenUrl, parameters, Map.class);
if (result == null) {
throw new RestClientException("access token endpoint returned empty result");
}
return extractAccessGrant(result);
}
The OAuth2Template setup:
final OAuth2Template oAuth2Template = new OAuth2Template(config.getClientId(), config.getClientSecret(),
GoogleOAuthConstants.AUTHORIZATION_SERVER_URL, GoogleOAuthConstants.TOKEN_SERVER_URL);
oAuth2Template.setUseParametersForClientAuthentication(true);