当前位置: 首页 > 知识库问答 >
问题:

keycloak:使用keycloak-admin为用户生成访问令牌

国兴文
2023-03-14

我必须将一个遗留的身份验证系统移到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;
await _keycloakAdmin.users.generateAccessToken(userId, realm, clientId, ...)

但我找不到。我只在这里找到了这个未回答的问题:Keycloak:REST API调用通过管理员用户名和密码获取用户的访问令牌

共有1个答案

阎宝
2023-03-14

解决方案相当复杂,并且(在撰写本文时)需要激活Keycloak名为令牌交换的“预览”特性。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的说明。

令牌交换的思想是,您为域的管理员获得令牌,然后将其交换为“普通”用户的令牌。为此,您必须为您的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的设置之后,您实际上可以发出两个调用,首先为域的管理员获取令牌,然后为具有特定用户ID的用户获取令牌。

获取管理令牌

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

 类似资料:
  • 我有一个Keycloak(独立)V1.9.4。最后在AWS实例上使用Wildfly 10安装安装程序,并尝试使用Keycloak(通过Keycloak的登录页面)和Twitter4j来验证Twitter用户,然后明显地让我的应用程序验证并查看用户的时间线等。 我已经配置了身份提供程序(Twitter)、领域和我的客户端应用程序。 我还在apps.Twitter.com上设置了一个Twitter应用

  • 我使用Keycloak来保护我的react前端和Node.js后端。这些客户端使用基于角色的授权进行保护。 我尝试这个endpoint来撤消用户访问令牌。但不起作用/auth/admin/realms//users/ 是否有方法在Keycloak中撤销特定用户的访问令牌?

  • 我试图使用从Spring应用程序中的公共客户端获取访问令牌。 谁能帮我弄清楚我做错了什么吗?

  • 我试图在一个spring boot项目中用KeyCloak的/usersendpoint创建用户。以下是我所遵循的步骤:首先在master领域中创建一个admin和admin-cli客户端。用于获取keycloak的实例以进行进一步的操作。 如果不在user中添加客户端表示,则可以创建用户。如果我在userRepresentation对象中添加CredentialRepresentation,我将

  • 我试图用java-admin-client创建一个新用户。我使用keycloak UI在我的领域中创建了一个新客户机。 代码: 最后一行是给我403禁止。