Keycloak 缺少表单参数:grant_type

Posted

技术标签:

【中文标题】Keycloak 缺少表单参数:grant_type【英文标题】:Keycloak Missing form parameter: grant_type 【发布时间】:2019-05-16 15:17:01 【问题描述】:

我的本​​地机器上运行着独立的 keycloak。

我创建了一个名为“spring-test”的新领域,然后创建了一个名为“login-app”的新客户端

根据其余文档:

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


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

应该给我 jwt 令牌,但我收到了错误的响应请求


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

我假设我的配置中缺少某些东西。

编辑: 我使用的是 json body 但它应该是application/x-www-form-urlencoded: 以下主体有效:

token_type_hint:access_token&token:token&client_id:client_id&client_secret:client_secret

【问题讨论】:

【参考方案1】:

您应该在 POST 请求中发送数据,并将 Content-Type 标头值设置为 application/x-www-form-urlencoded,而不是 json。

【讨论】:

我仍然有同样的问题,即使我将内容类型设置为 urlencoded: curl -d '"grant_type": "password", "username": "user", "密码": "pass", "client_id": "login-app"' -H "Content-Type: application/x-www-form-urlencoded" -X POST "localhost:8082/auth/realms/ina-dev/protocol/openid-connect/…" "error":"invalid_request ","error_description":"缺少表单参数:grant_type" 因为是发送json数据,所以应该使用-d "param1=value1&param2=value2" 语法 这不起作用。你如何在邮递员@ipave 中设置-d 的东西? @Avión 这是一个链接 - learning.getpostman.com/docs/postman/sending_api_requests/… 谢谢,我发送的是“multipart/form-data;boundary=-------------------------616846104444017186133807” 【参考方案2】:

带卷发

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'

邮递员 (参数选择 x-www-form-urlencoded 选项)

【讨论】:

别忘了把client_secret【参考方案3】:

对于curl有问题的人,curl命令如下

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"

curl 命令可以在没有 Content-Type 标头的情况下工作。

【讨论】:

【参考方案4】:

对于那些通过搜索寻找javascript 解决方案而来到这里的人。

以下是使用axioscodekeycloak 权限交换access_token 的示例。

本例使用querystring:

npm install querystring

yarn add querystring

发送请求:


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);

);

您需要在请求正文中发送带有参数的 POST 请求作为 URL 编码的字符串。

FormData 对象不起作用。

【讨论】:

有一种简单的方法可以在不使用查询字符串的情况下获取令牌。 const config = headers: 'Content-Type': 'application/x-www-form-urlencoded' ;常量 formParameter = client_id=KEYCLOAK_CLIENT_ID&amp;client_secret=KEYCLOAK_CLIENT_SECRET&amp;grant_type=KEYCLOAK_API_GRANT_TYPE; axios.post(REQUEST_URL,formParameter,config); Pavan J 发布了一个Answer 说“感谢@marc 的解决方案,它有效!我一直在很多论坛中寻找这个解决方案。PS:grant_type 中有一个错字: 'authorization_code',(缺少右引号)"【参考方案5】:

这是一个 CURL 命令示例

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'

【讨论】:

【参考方案6】:

我在 SOAPUI 测试中遇到了类似的问题。我们不应该发布 json。当我清除“媒体类型”并选中“PostQueryString”复选框时,这个问题得到了解决。 “媒体类型框”将自行设置为“www-form-urlencoded”。通过点击加号在顶部添加属性。

【讨论】:

以上是关于Keycloak 缺少表单参数:grant_type的主要内容,如果未能解决你的问题,请参考以下文章

KeyCloak 与 Azure ADB2C 集成 - 缺少状态参数

Keycloak登录表单

请求 OAUTH 令牌调查猴子 v3 时缺少参数

Keycloak 直接访问授权在 keycloak userinfo 端点上无效

Keycloak 返回已经过期的令牌

Keycloak:缺少领域公钥