从 keycloak 获取访问令牌的 POST 请求失败

Posted

技术标签:

【中文标题】从 keycloak 获取访问令牌的 POST 请求失败【英文标题】:POST request to get access token from keycloak fails 【发布时间】:2021-03-21 01:55:42 【问题描述】:

我正在尝试从 keycloak 的 REST-API 获取访问令牌:

library(jsonlite)
library(httr)

admin_user <- list(
  username = "admin",
  password = "admin",
  grant_type = "password",
  client_id = "admin_cli"
)
tkn01 <- POST(
  "https://www.example.com/auth/realms/master/protocol/openid-connect/token",
  body = toJSON(admin_user),
  add_headers(.headers = c("Content-Type" = "application/x-www-form-urlencoded"))
)

这会导致错误:

rawToChar(tkn01$content)
[1] "\"error\":\"invalid_request\",\"error_description\":\"Missing form parameter: grant_type\""

虽然已经提供了grant_type

我也试过curl

curl -i -X POST -d '"username":"admin","password":"admin","grant_type":"password","client_id":"admin_cli"' https://www.example.com/auth/realms/master/protocol/openid-connect/token
HTTP/1.1 400 Bad Request
Server: nginx/1.17.8
Date: Wed, 09 Dec 2020 16:27:14 GMT
Content-Type: application/json
Content-Length: 84
Connection: keep-alive
Cache-Control: no-store
X-XSS-Protection: 1; mode=block
Pragma: no-cache
X-Frame-Options: SAMEORIGIN
Referrer-Policy: no-referrer
Strict-Transport-Security: max-age=15724800; includeSubDomains
X-Content-Type-Options: nosniff

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

【问题讨论】:

【参考方案1】:

您发布的是 JSON 结构,这是错误的。您只需要将其发布为参数/字段。卷曲示例:

curl -s -X POST \
  --data "scope=$SCOPE" \
  --data-urlencode "client_id=$CLIENTID" \
  --data-urlencode "client_secret=$CLIENTSECRET" \
  --data-urlencode "username=$USERNAME" \
  --data-urlencode "password=$PASSWORD" \
  --data-urlencode "grant_type=password" \
  https://www.example.com/auth/realms/master/protocol/openid-connect/token

【讨论】:

谢谢,但我收到错误 "error":"unauthorized_client","error_description":"INVALID_CREDENTIALS: Invalid client credentials"。我试过这个:curl -s -X POST --data-urlencode "username=admin" --data-urlencode "client_id=admin_cli" --data-urlencode "password=admin" --data-urlencode "grant_type=password" https://www.example.com/auth/realms/master/protocol/openid-connect/token。在这种情况下我需要scopeclient_secret 吗?最终,我想获得一个 access_token 并使用它通过 REST-API 创建用户。 @eastclintw00d 你需要client_secret 如果使用的客户端(admin_cli 在你的情况下)不是公共客户端(通常默认 keycloak admin-cli 客户端是公共的,但看起来你使用的是不同的一个admin_cli,所以不清楚是否公开)。 scope is also required, at least openid` 范围。 好的,我有一个错字:admin_cli 而不是admin-cli。这有效:curl -s -X POST --data-urlencode "username=admin" --data-urlencode "client_id=admin-cli" --data-urlencode "password=admin" --data-urlencode "grant_type=password" https://www.example.com/auth/realms/master/protocol/openid-connect/token。再次感谢!

以上是关于从 keycloak 获取访问令牌的 POST 请求失败的主要内容,如果未能解决你的问题,请参考以下文章

如何使用邮递员从 keycloak 获取访问令牌(授权码流)

访问令牌后的Keycloak授权过程

无法从 Keycloak 获取 oauth 令牌

Keycloak 访问令牌与 UserInfo 令牌?

撤销 Keycloak 访问令牌

除了 keycloak 令牌之外,我还需要其他任何东西来访问使用 keycloak 保护的服务吗?