首页 > 解决方案 > 如何配置 Keycloak 并通过 REST API 完成所有步骤并获得 JWT?

问题描述

我需要使用领域、具有凭据的用户和客户端配置在 Docker 中运行的 Keycloak,然后像此博客文章中一样获取 JWT 。如果我使用如图所示的 UI,它可以工作,但我需要通过 Keycloak REST API 自动执行所有步骤。当我这样做时,所有步骤似乎都有效,但获取 JWT 失败。

我像这样在 Docker 中运行 Keycloak

docker network create keycloak-network

docker run --name mysql -d \
  --net keycloak-network \
  -e MYSQL_DATABASE=keycloak \
  -e MYSQL_USER=keycloak \
  -e MYSQL_PASSWORD=password \
  -e MYSQL_ROOT_PASSWORD=root_password \
  mysql:8.0.22

docker run -d -it \
  -e DB_VENDOR=mysql \
  -e KEYCLOAK_USER=admin \
  -e KEYCLOAK_PASSWORD=admin \
  --name keycloak \
  --net keycloak-network \
  -p 8080:8080 \
  jboss/keycloak:11.0.3

我从主领域获得访问令牌

POST -H "Content-Type: application/x-www-form-urlencoded" -d "username=admin" -d "password=admin" -d "grant_type=password" -d 'client_id=admin-cli' "http://localhost:8080/auth/realms/master/protocol/openid-connect/token"|jq -r '.access_token'

然后我创建我的领域(命名testrealm

POST -H "Authorization: Bearer ${ACCESS_TOKEN}" -H "Content-Type: application/json" -d @"${REALM_FILE}" "http://localhost:8080/auth/admin/realms"

然后我创建一个具有凭据的用户:

POST "http://localhost:8080/auth/admin/realms/testrealm/users" --header 'Content-Type: application/json' -H "Authorization: Bearer ${ACCESS_TOKEN}" -d {"enabled":true,"username":"testuser","email":"test.user@gmail.com","firstName":"test","lastName":"user","credentials":[{"type":"password","value":"abc123","temporary":false}]}

我可以在 UI 中看到新用户,并在新用户凭据中看到一个输入密码的条目。

我创建了一个客户端(名为testclient

POST -H "Authorization: Bearer ${ACCESS_TOKEN}" -H "Content-Type: application/json" -d @"${CLIENT_FILE}" "http://localhost:8080/auth/admin/realms/testrealm/clients"

我获得了修改新客户端所需的 ID

GET -H "Accept: application/json" -H "Authorization: Bearer ${ACCESS_TOKEN}" "http://localhost:8080/auth/admin/realms/testrealm/authentication/flows"

从 Alias 中提取 BROWSER_ID 并从 Aliasbrowser中提取 DIRECT_GRANT_ID direct grant

我更新客户端更改Access TypeconfidentialAuthentication Flow OverridesBrowser FlowDirect Grant Flow

PUT -H "Authorization: Bearer ${ACCESS_TOKEN}" -H "Content-Type: application/json" --data @client.update.json "http://localhost:8080/auth/admin/realms/testrealm/clients/${clientId}"

数据在哪里

{                                                                               
    "publicClient": false,        
    "clientAuthenticatorType": "client-secret",                                            
    "authenticationFlowBindingOverrides": {                                                                 
        "direct_grant":"${DIRECT_GRANT_ID}",
        "browser":"${BROWSER_ID}"
    }
} 

我得到了客户的秘密

GET -H "Accept: application/json" -H "Authorization: Bearer ${ACCESS_TOKEN}" http://localhost:8080/auth/admin/realms/testrealm/clients/${CLIENT_ID}/client-secret

此时,如果我进入 UI,它会显示我返回的相同客户端密码,并且客户端Access Typeconfidential并且Authentication Flow Overrides被设置为browserand direct grant。一切看起来都是正确的。现在,Keycloak 服务器的配置应该与通过 UI 完成时的配置相同,如帖子中所示。

当我使用帖子中所示的 curl 命令获取 JWT 时

curl -L -X POST http://localhost:8080/auth/realms/testrealm/protocol/openid-connect/token -H 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'client_id=testclient' --data-urlencode 'grant_type=password' --data-urlencode 'client_secret=544479de-72a4-44c7-9420-3a142cd699c6' --data-urlencode 'scope=openid' --data-urlencode 'username=testuser' --data-urlencode 'password=abc123'

给出一个错误,说 https 是必需的。

{"error":"invalid_request","error_description":"HTTPS required"}

但是通过 UI 完成配置时不需要 https。事实上,所有请求都是通过 http 发送的,而不是 https。

然后使用 https

curl -L -X POST https://localhost:8080/auth/realms/testrealm/protocol/openid-connect/token -H 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'client_id=testclient' --data-urlencode 'grant_type=password' --data-urlencode 'client_secret=544479de-72a4-44c7-9420-3a142cd699c6' --data-urlencode 'scope=openid' --data-urlencode 'username=testuser' --data-urlencode 'password=abc123'

我收到这个错误

curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number

如果我通过 UI 配置 Keycloak,curl 命令可以工作,所以我在使用REST API. Keycloak 文档没有显示这个用例,所以它们在这里没有帮助。

有谁知道我在使用时错过了REST API什么?

标签: keycloakkeycloak-rest-api

解决方案


发布 Keycloak 容器的 8443 端口。将有带有自签名证书的 https(因此在您的请求中禁用 tls 验证):

docker run -d -it \
 -e DB_VENDOR=mysql \
 -e KEYCLOAK_USER=admin \
 -e KEYCLOAK_PASSWORD=admin \
 --name keycloak \
 --net keycloak-network \
 -p 8443:8443 \
 jboss/keycloak:11.0.3

Keycloak 将在https://localhost:8443. 请参阅需要 Keycloak Docker HTTPS


推荐阅读