密钥掩蔽:使用keyshaak-admin为用户生成访问令牌 [英] Keycloak: Generate access token for a user with keycloak-admin

查看:17
本文介绍了密钥掩蔽:使用keyshaak-admin为用户生成访问令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须将旧的身份验证系统移到Keyshaak,并且我无法更改客户端上的实际工作流。因此,我需要使用我的API(在node.js中)提供一个用户创建和登录系统,该系统代表用户从Keyshaak创建和获取访问令牌。

我能够创建用户,但我还没有找到为该用户生成访问令牌的方法。我找到的唯一解决办法是创建一个用户并设置一个随机密码,然后要求授予该用户提供用户名和密码的权限,但这意味着我必须在我这边存储密码,这正是我想要迁移到Keyloak的原因。

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;

我不敢相信不存在一种更优雅的方法来完成它,所以我认为我在Keyloak客户端的配置以及在理解一些基本概念和命名约定方面遗漏了一些基本的东西。我本以为会是

await _keycloakAdmin.users.generateAccessToken(userId, realm, clientId, ...)

但我找不到它。我只在这里找到了这个未回答的问题:Keycloak :REST API call to get access token of a user through admin username and password

推荐答案

该解决方案相当复杂,需要(在撰写本文时)激活名为令牌交换的密钥罩的预览和功能。该过程在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中的说明。

首先,您需要在运行Keyloak时将开关-Dkeycloak.profile=preview添加到JAVA_OPTS,以启用令牌交换功能。要检查Keyloak是否加载了预览功能,请查看配置文件部分下的/auth/admin/master/console/#/server-info中的服务器信息:

令牌交换的理念是,您获取领域管理员的令牌,然后将其交换为普通用户的令牌(&Q;;NORMAL&Q;USER)。 为此,您必须为密钥罩领域创建(如果您还没有)两个不同的客户端:第一个是管理员用来获取令牌的";起始客户端;第二个是您要为";Normal";用户提供令牌的";目标客户端";。

之后,您需要为您的领域创建一个admin用户。您可以按照Keycloak - Create Admin User in a Realm

中的说明进行操作

然后,您需要使目标客户端能够接受令牌交换。您应该仔细遵循https://www.keycloak.org/docs/latest/securing_apps/index.html#_client_to_client_permission中的说明 此过程分为两步:创建客户端策略,该策略指定哪些";启动客户端可以交换令牌,然后启用目标客户端的权限,并将刚创建的策略附加到token-exchange权限:

设置密钥罩后,您实际上可以发出两个调用,首先获取领域管理员的令牌,然后获取具有特定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'

正常用户令牌的Exchange管理令牌

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

这篇关于密钥掩蔽:使用keyshaak-admin为用户生成访问令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆