【问题标题】:Keycloak Missing form parameter: grant_typeKeycloak 缺少表单参数: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}

【问题讨论】:

    标签: java authentication keycloak


    【解决方案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 的东西?
    • 谢谢,我发送的是“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 解决方案而来到这里的人。

      以下是使用axios 将code 与keycloak 权限交换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”。通过点击加号在顶部添加属性。

        【讨论】:

          猜你喜欢
          • 2021-01-04
          • 1970-01-01
          • 2012-06-27
          • 1970-01-01
          • 1970-01-01
          • 2014-10-14
          • 2019-12-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多