如何配置 Keycloak 并通过 REST API 完成所有步骤并获得 JWT?

How do I configure Keycloak and get a JWT with all steps done through the REST API?

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

我 运行 Keycloak 在 Docker 像这样

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"

正在从别名 browser 中提取 BROWSER_ID 并从别名 direct grant 中提取 DIRECT_GRANT_ID。

我更新客户端,将 Access Type 更改为 confidential 并使用 Authentication Flow Overrides 更改 Browser 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分别设置为 browserdirect grant。一切看起来都是正确的。 Keycloak 服务器现在应该配置为与通过 UI 完成时相同,如 post.

所示

当我使用post中所示的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 时错过了什么吗?

发布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 上可用。参见