Keycloak Missing form parameter: grant_type

JavaAuthenticationKeycloak

Java Problem Overview


I have keycloak standalone running on my local machine.

I created new realm called 'spring-test', then new client called 'login-app'

According to the rest documentation:

POST: http://localhost:8080/auth/realms/spring-test/protocol/openid-connect/token

{
    "client_id": "login-app",
    "username": "user123",
    "password": "pass123",
    "grant_type": "password"
}

should give me the jwt token but I get bad request with response

{
    "error": "invalid_request",
    "error_description": "Missing form parameter: grant_type"
}

I am assuming that something is missing in my configuration.

EDIT: I was using json body but it should be application/x-www-form-urlencoded: the following body works:

token_type_hint:access_token&token:{token}&client_id:{client_id}&client_secret:{client_secret}

Java Solutions


Solution 1 - Java

You should send your data in a POST request with Content-Type header value set to application/x-www-form-urlencoded, not json.

Solution 2 - Java

With Curl

curl -X POST \
http://localhost:8080/auth/realms/api-gateway/protocol/openid-connect/token \
-H 'Accept: */*' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Length: 73' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Cookie: JSESSIONID=F8CD240FF046572F864DC37148E51128.a139df207ece;   JSESSIONID=65D31B82F8C5FCAA5B1577DA03B4647C' \
-H 'Host: localhost:8080' \
-H 'Postman-Token: debc4f90-f555-4769-b392-c1130726a027,d5087d9f-9253-48bd-bb71-fda1d4558e4d' \
-H 'User-Agent: PostmanRuntime/7.15.2' \
-H 'cache-control: no-cache' \
-d 'grant_type=password&client_id=api-gateway&username=admin&password=temp123'

By Postman (Select x-www-form-urlencoded option for parameters)

enter image description here

Solution 3 - Java

For those having problems with curl the curl command is as follows

curl -d "client_secret=<client-secret>" -d "client_id=<client-id>" -d "username=<username>" -d "password=<password>" -d "grant_type=password" "http://localhost:8080/auth/realms/<realm-name>/protocol/openid-connect/token"

The curl command works without the Content-Type header.

Solution 4 - Java

For those who landed here from a search looking for JavaScript solution.

Here is an example when exchanging code for access_token with keycloak authority using axios.

querystring is used in this example:

npm install querystring

or

yarn add querystring

Sending the request:


import queryString from 'querystring'

const params = {

    grant_type: 'authorization_code',
    client_id: 'client-id-here',
    code: 'code-from-previous-redirect',
    redirect_uri: location.protocol + '//' + location.host

};

axios({

    method: 'post',
    url: 'https://my-keycloak.authority/token',
    data: queryString.stringify(params),
    config: {
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }

}).then(response => {

    console.log(response.data);

}).catch(error => {

    console.error(error);

});

> You are required to send a POST request with the parameters as a URL encoded string in the request body. > > FormData object does not work.

Solution 5 - Java

Here's a sample CURL command

curl -X POST \
  http://localhost:8080/auth/realms/your_realm_name/protocol/openid-connect/token \
  -H 'Accept: */*' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 69' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Cookie: KC_RESTART=' \
  -H 'Host: localhost:8080' \
  -H 'Postman-Token: 88f38aa0-8659-4b37-a2aa-d6b92177bdc2,29c4e7db-51f4-48d1-b6d5-daab06b68ab4' \
  -H 'User-Agent: PostmanRuntime/7.20.1' \
  -H 'cache-control: no-cache' \
  -d 'client_id=my-app&username=admin&password=admin123&grant_type=password'

Solution 6 - Java

I had similar issue in SOAPUI testing. We should not POST a json. This got resolved when I cleared 'Media Type' and checked 'PostQueryString' checkbox. 'Media Type box' will set to 'www-form-urlencoded' by itself. Add attributes at Top by hitting plus sign.

enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBorislav StoilovView Question on Stackoverflow
Solution 1 - JavaipaveView Answer on Stackoverflow
Solution 2 - JavaRobin MathurView Answer on Stackoverflow
Solution 3 - JavaAdnan KhanView Answer on Stackoverflow
Solution 4 - JavaMarcView Answer on Stackoverflow
Solution 5 - JavaLanil MarasingheView Answer on Stackoverflow
Solution 6 - JavaRohit TewariView Answer on Stackoverflow