# 将 name claim 映射到 username (nickname)，而非 preferred\_username claim

**URL:** <https://meta.discourse.org/t/mapping-the-name-claim-rather-than-the-preferred-username-claim-to-the-username-nickname/304285>\
**Category:** SSO\
**Tags:** openid-connect\
**Created:** [2023年十月25日 02:38 UTC](https://meta.discourse.org/t/mapping-the-name-claim-rather-than-the-preferred-username-claim-to-the-username-nickname/304285 "2023-10-25T02:38:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Frank\_L](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/frank_l/32/335485_2.png) [@Frank\_L](https://meta.discourse.org/u/Frank_L)\
**Post date:** [2023年十月25日 02:38 UTC](https://meta.discourse.org/t/mapping-the-name-claim-rather-than-the-preferred-username-claim-to-the-username-nickname/304285/1 "2023-10-25T02:38:42Z")

</div>

有人知道是否可以将 `name` 声明映射到注册期间和“创建帐户”弹出窗口中显示的用户名（昵称），而不是 `preferred_username` 声明吗？

这是我们从 Keycloak 收到的信息：

```json
{
  ...
  "scope": "openid email",
  "sid": "f0f20a2a-19e5-4581-8a45-c1250376f226",
  "email_verified": true,
  "name": "Ted Bush",
  "preferred_username": "tb",
  "given_name": "Ted",
  "family_name": "Bush",
  "email": "ted.bush@example.com"
  ...
}

```

默认情况下，`preferred_username`（在此示例中为“tb”）用作用户名（昵称）。

但是，我们希望以这种方式配置集成，以便使用 `name`（“Ted Bush”）作为用户名（昵称）。

谢谢。

---

<div class="post-metadata">

**Author:** ![Frank\_L](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/frank_l/32/335485_2.png) [@Frank\_L](https://meta.discourse.org/u/Frank_L)\
**Post date:** [2023年十月28日 03:50 UTC](https://meta.discourse.org/t/mapping-the-name-claim-rather-than-the-preferred-username-claim-to-the-username-nickname/304285/2 "2023-10-28T03:50:42Z")

</div>

我在“用户”设置部分看到了“建议用户名时使用用户的全名”设置。但它似乎对 OpenID Connect 没有影响？

或者这对任何人都有用吗？

---

<div class="post-metadata">

**Author:** ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)\
**Post date:** [2023年十月28日 07:20 UTC](https://meta.discourse.org/t/mapping-the-name-claim-rather-than-the-preferred-username-claim-to-the-username-nickname/304285/3 "2023-10-28T07:20:02Z")

</div>

> [@Frank\_L](#):
>
> 有人能用这个吗？

是的，我在使用 Google OAuth2 服务器作为 OpenID Connect 提供商进行测试时，它对我来说是有效的。

我认为您遇到的问题与 Discourse 用户名建议器代码的工作方式有关。Keycloak 返回一个 `preferred_username`。如果在身份提供商返回的 userinfo 中设置了 `preferred_username`，它将优先于 `name` 或 `given_name`/`family_name` 字段的值。

供参考，问题发生在 这里（`preferred_username` 在一个在此时被调用的方法中被设置为 `username` 的值）：

> <https://github.com/discourse/discourse/blob/main/lib/auth/result.rb#L185-L190>

然后在这里：

> <https://github.com/discourse/discourse/blob/main/lib/user_name_suggester.rb#L7-L27>

由于 `preferred_username` 的值是传递给用户名建议器代码的第一个参数，因此它将被使用。这意味着 `use_name_for_username_suggestions` 设置在此情况下无效。我认为它的目的是处理身份提供商未返回 `preferred_username` 的情况。

我没有看到好的解决方法，除非您可以阻止从 Keycloak 将 `preferred_username` 传递给 Discourse。

---

<div class="post-metadata">

**Author:** ![Frank\_L](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/frank_l/32/335485_2.png) [@Frank\_L](https://meta.discourse.org/u/Frank_L)\
**Post date:** [2023年十月29日 02:08 UTC](https://meta.discourse.org/t/mapping-the-name-claim-rather-than-the-preferred-username-claim-to-the-username-nickname/304285/4 "2023-10-29T02:08:45Z")

</div>

@simon，你说得对；我已在测试 Keycloak 实例上验证了你提到的内容。当我将 Keycloak 配置为不将 `preferred_username` 传递给 Discourse 时，Discourse 的用户名建议器确实会使用名字和姓氏。

但是，我们无法以这种方式配置我们的生产 Keycloak，因为客户端配置与多个其他客户端共享，而不仅仅是 Discourse。

如果在插件中有一种方法可以影响这种行为，那将是有益的。
