【问题标题】:How to get user id, and user UUID/GUID from Keycloak?如何从 Keycloak 获取用户 ID 和用户 UUID/GUID?
【发布时间】:2023-03-26 04:04:01
【问题描述】:

我在 docer 中使用 Keycloak 并托管在 https://accounts.example.com

我使用 React 作为我的客户端库,登录后,用户进入 https://user.example.com

此 React 客户端使用位于 https://api.user.example.com 的 .NET Core API。

我使用keycloak.js 来管理 React 面板中的访问。

现在假设用户想要创建一张票。我将此票信息发送到 API:

{
    title: 'Urgent backup',
    priority: 'urgent',
    description: 'Please backup my files immediately'
}

在我们的数据库中,我们有这样的设计:

create table Tickets
(
    Id bigint not null primary identity(1, 1),
    UserGuid uniqueidentifier not null, -- How should I fill this column?
    Title nvarchar(200) not null,
    PriorityId int not null,
    Description nvarchar(max) not null
)

问题是,API 应该从用户那里提取永久数据。

我当然不能在该列中存储emailusername。我什至不能依赖 usernameemail 因为 Keycloak 的管理面板允许配置此设置:

因此,最好的选择是在 Keycloak 中给用户一个 GUIDUUID,并在 open id 令牌中检索它。

我搜索过,但找不到如何执行此操作。

你能帮忙吗?

【问题讨论】:

    标签: reactjs .net-core keycloak


    【解决方案1】:

    默认情况下,您的访问令牌应该有一个主题 (sub) 声明,其值为 Keycloak 中的用户 ID。那是一个UUID。 您可以从令牌中提取该 ID 并使用它。

    也许 ASP.NET 核心会自动执行此操作,并为您提供主题声明作为用户名。

    【讨论】:

      【解决方案2】:

      我不确定问题到底出在哪里,Keycloak 已经提供了获取/更新/删除用户的 API

      Get users 返回用户列表,根据查询参数过滤:

      GET /{realm}/users
      

      在查询参数中,您可以根据电子邮件/名字/姓氏/用户名进行过滤

      如果你想获取所有用户,它会给出类似的结果

      [
           {
              "id":"569f67de-36e6-4552-ac54-e52085109818",
              "username":"user1",
              "enabled":true,
              ...
           },
           {
              "id":"90afb701-fae5-40b4-8895-e387ba34902jh",
              "username":"user2",
              "enabled":true,
              ....
           }
        ]
      

      如果你想获取单个用户,你也可以使用下面的 API 来获取它

      GET /{realm}/users/{id}
      

      如果您看到第一个其余查询,您可以根据您的要求使用查询参数进行查询并获取结果,然后id 可以用于您的第二个表。

      编辑 -

      默认情况下,可以直接从principal获取User ID

      String userId = accessToken.getSubject();
      

      在 .Net Core 中我发现了这个

      public static T GetLoggedInUserId<T>(this ClaimsPrincipal principal)
          {
              if (principal == null)
                  throw new ArgumentNullException(nameof(principal));
      
              var loggedInUserId = principal.FindFirstValue(ClaimTypes.NameIdentifier);
      
              if (typeof(T) == typeof(string))
              {
                  return (T)Convert.ChangeType(loggedInUserId, typeof(T));
              }
              else if (typeof(T) == typeof(int) || typeof(T) == typeof(long))
              {
                  return loggedInUserId != null ? (T)Convert.ChangeType(loggedInUserId, typeof(T)) : (T)Convert.ChangeType(0, typeof(T));
              }
              else
              {
                  throw new Exception("Invalid type provided");
              }
          }
      

      【讨论】:

      • 我知道我可以使用管理 API 来获取用户列表。但我不知道如何从 OIDC 令牌中提取用户 UUID。
      猜你喜欢
      • 2018-01-29
      • 2020-05-30
      • 1970-01-01
      • 2019-08-27
      • 2013-11-23
      • 2017-06-17
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      相关资源
      最近更新 更多