Issue
I implemented a KeyCloak client with the following configuration: keycloak configuration
And I implemented my callback endpoint like that:
@GetMapping("/callback")
@ResponseBody
public String getToken(@RequestParam String code) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString());
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("code", code);
map.add("client_id", "spring-login-app");
map.add("client_secret", "");
map.add("grant_type", "authorization_code");
map.add("redirect_uri", UriComponentsBuilder.fromHttpUrl("http://127.0.0.1:3002/callback").build().toString());
HttpEntity formEntity = new HttpEntity<MultiValueMap<String, String>>(map, headers);
try {
ResponseEntity<KeycloakTokenResponse> response =
restTemplate.exchange("http://127.0.0.1:8080/auth/realms/raroc/protocol/openid-connect/token",
HttpMethod.POST,
formEntity,
KeycloakTokenResponse.class);
KeycloakTokenResponse resp = response.getBody();
return resp.getAccess_token();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return "nothing";
}
The problem is when I tried to get my access token from this callback endpoint, I received a 400 Bad Request error with the following message: 400 Bad Request: "{"error":"invalid_grant","error_description":"Incorrect redirect_uri"}"
When I test it through postman with the same x-www-form-url-encoded form params, it works fine, but in spring, it's impossible to do it.
I tried many scenario for the "redirect_uri" param, just a String, an UriComponentsBuilder.formHttpUrl, some other URL encoder thing but unfortunately I still have this error.
Solution
You can try to specify a: http://localhost:3002/*
instead of your actual redirect URI in the KeyCloak configuration but from what I read in your settings, everything looks good.
Be careful also sometimes if you are changing the configuration of Keyloak, you need to restart it to take the changes into account.
If you want to test also a full scenario, open an incognito tab with your browser, and it should work.
Answered By - JStw
Answer Checked By - Pedro (JavaFixing Volunteer)