我必须将遗留身份验证系统移到Keycloak,并且无法更改客户端上的实际工作流。因此,我需要在我的api (在node.js中)中提供一个用户创建和登录系统,该系统代表用户创建并从Keycloak获得访问令牌。
我能够创建一个用户,但我还没有找到为该用户生成访问令牌的方法。我找到的唯一解决办法是创建一个用户并设置一个随机密码,然后请求授予提供用户名和密码的用户,但这意味着我必须在自己的一侧存储一个密码,这正是我想要迁移到Keycloak的原因。
const KcAdminClient = require('keycloak-admin').default;
const Keycloak = require('keycloak-connect');
const _keycloakAdmin = new KcAdminClient({
baseUrl: process.env.KEYCLOAK_SERVER_AUTH_URL,
realm: process.env.KEYCLOAK_REALM
});
await _keycloakAdmin.auth({
realm: process.env.KEYCLOAK_REALM,
username: process.env.KEYCLOAK_USER,
password: process.env.KEYCLOAK_PASSWORD,
grantType: 'password',
clientId: process.env.KEYCLOAK_CLIENT_ID,
});
//Create a user and set password
const newUser = await _keycloakAdmin.users.create({
realm: process.env.KEYCLOAK_REALM,
username: 'something',
email: 'someone@domain.com',
firstName: 'Some',
lastName: 'One',
emailVerified: true,
enabled: true,
});
await _keycloakAdmin.users.resetPassword({
realm: process.env.KEYCLOAK_REALM,
id: newUser.id,
credential: {
temporary: false,
type: 'password',
value: 'randompassword'
}
});
//generate a token for the user
const _keycloak = new Keycloak({}, {
clientId: process.env.KEYCLOAK_CLIENT_ID,
serverUrl: process.env.KEYCLOAK_SERVER_AUTH_URL,
realm: process.env.KEYCLOAK_REALM,
credentials: {
secret: process.env.KEYCLOAK_CLIENT_SECRET
}
});
const grant = await _keycloak.grantManager.obtainDirectly('something', 'randompassword');
const access_token = grant.access_token.token;我无法相信没有一种更优雅的方法来做到这一点,所以我认为在我的Keycloak客户端的配置和理解一些基本的概念和命名约定方面,我缺少了一些基本的东西。我就会料到
await _keycloakAdmin.users.generateAccessToken(userId, realm, clientId, ...)但我没能找到。我只在这里找到了这个未回答的问题:Keycloak :REST API call to get access token of a user through admin username and password
发布于 2021-03-24 07:44:06
该解决方案相当复杂,需要激活密钥披风的“预览”功能,称为令牌交换( Token )。这个过程在https://www.keycloak.org/docs/latest/securing_apps/index.html#_token-exchange中进行了描述,对于我的具体情况,我遵循了https://www.keycloak.org/docs/latest/securing_apps/index.html#internal-token-to-internal-token-exchange的说明。
首先,您需要启用令牌交换功能,在运行密钥披风时将开关-Dkeycloak.profile=preview添加到JAVA_OPTS。要检查Keycloak加载的预览功能,请查看配置文件下面的/auth/admin/master/console/#/server-info上的服务器信息:

令牌交换的思想是,您为您的领域的管理员获得一个令牌,然后将它交换为一个“正常”用户的令牌。要做到这一点,您必须为Keycloak领域创建两个不同的客户端(如果您还没有):第一个客户端是管理员用来获取令牌的“启动客户端”,第二个客户端是您希望为“普通”用户提供令牌的“目标客户端”。
之后,您需要为您的领域创建一个管理用户。您可以按照Keycloak - Create Admin User in a Realm的说明进行操作
然后,您需要使目标客户端能够接受令牌交换。您应该仔细遵循https://www.keycloak.org/docs/latest/securing_apps/index.html#_client_to_client_permission的说明--这是一个两步的过程:创建客户端策略,指定哪些“启动客户端”可以交换令牌,然后为目标客户端启用权限,并将刚刚创建的策略附加到token-exchange权限:

在完成了设置Keycloak之后,您实际上可以发出两个调用,首先为领域管理员获取令牌,然后使用特定的userId为用户获取令牌。
获取管理令牌
curl --location --request POST '<your_url>/auth/realms/<your_realm>/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=<your_starting_client>' \
--data-urlencode 'username=<your_admin_username>' \
--data-urlencode 'password=<your_admin_password>' \
--data-urlencode 'realm=<your_realm>' \
--data-urlencode 'scope=openid'用于“正常”用户令牌的交换管理令牌
curl --location --request POST '<your_url>/auth/realms/<your_realm>/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'client_id=<your_starting_client>' \
--data-urlencode 'subject_token=<your_admin_token>' \
--data-urlencode 'requested_token_type=urn:ietf:params:oauth:token-type:refresh_token' \
--data-urlencode 'audience=<your_target_client>' \
--data-urlencode 'requested_subject=<your_target_user_id>'根据客户端的配置,您可能最终必须在第二次调用中指定一个client_secret。
https://stackoverflow.com/questions/65714161
复制相似问题