用户组通过 ADFS 上的 OpenID Connect 声明

User groups as claims through OpenID Connect over ADFS

我需要帮助来弄清楚如何通过基于 ADFS 的 OpenID 连接获取用户的分配组 (Windows Server 2016)。我目前能够对用户进行身份验证并获取用户信息,包括 access_token。当我检查 JWT 令牌时,我可以在其中看到所有默认声明。我想要的是将所有用户分配的系统组作为字符串数组添加到声明中,但我不知道如何完成此操作。 ADFS 和 Windows 服务器是一个野兽,Google 的所有搜索结果都没有引导我朝着正确的方向前进。我找到的所有文章都有点没用,因为如果您没有受过整个 ADFS shebang 的教育,它们要么在步骤中不完整,要么难以理解。

我已经被这个问题困了几天了,需要一些帮助,希望有人知道这方面的知识。

到目前为止我做了什么:

  1. 我向 ADFS 添加了一个应用程序组,其中包含一个 "Server Application" 和一个 "Web API"。
  2. 我添加了一个名为 Admin 的用户组,并将其分配给了一个名为 max 的用户。
  3. 我可以通过 ADFS 上的 OpenID Connect 登录并从用户信息端点获取用户信息。
  4. 我已经能够解码 access_token 以访问声明。

我目前正在使用范围 "openid"、"email" 和 "profile" 进行身份验证。

您可以使用网络浏览器访问网络应用程序。

这使您可以访问声明规则 - 就像您示例中的网络 API 一样。

然后使用具有 "Token-Groups" 选项之一的 LDAP 规则,例如"Unqualified" 并将其映射到 "Role".

类型

这会将所有组添加到令牌中,每个组一个角色声明。

我们一切正常,所以我只是想如果其他人想做我们所做的,我会分享我们所做的。

先决条件

要执行以下步骤,您需要 Windows Server 2016 或更高版本并启用 "Active Directory Federation Services (ADFS)" 功能。

将 OpenID Connect 配置添加到 ADFS

  1. 打开服务器管理器右上角 "Tools" 菜单下的 "AD FS Management" 工具。
  2. Select 左侧边栏中的 "Application Groups" 文件夹项。
  3. 单击右侧边栏中的 "Add Application Group..."。
  4. 为应用组命名,例如"OpenID Connect"
  5. Select "Server application accessing a web API" 列表项并单击下一步。
  6. 客户端标识符复制并粘贴到文本文件中供以后使用。
  7. 输入您的身份验证 "Redirect URI" 并单击下一步。
  8. 勾选 "Generate a shared secret" 框。将 Secret 复制并粘贴到用于您的应用程序的文本中。点击下一步。
  9. 粘贴并添加 Client Identifier(来自第 6 步)作为 "Identifier"。点击下一步。
  10. Select 您要使用的访问控制策略,然后单击下一步。
  11. 确保勾选 "openid" 旁边的框。
  12. 点击下方的"New scope..."按钮,并命名为"allatclaims",点击确定。需要此范围来提供附加信息作为声明,例如用户的组。
  13. 完成向导。

配置 OpenID Connect 以提供用户组作为声明

  1. 打开服务器管理器右上角 "Tools" 菜单下的 "AD FS Management" 工具。
  2. Select 左侧边栏中的 "Application Groups" 文件夹项。
  3. 双击之前添加的组,然后双击 "Web API" 应用程序。
  4. Select 名为 "Issuance Transform Rules" 的选项卡。
  5. 点击底部的"Add Rule..."按钮。
  6. Select"Send LDAP Attributes as Claims"点击下一步
  7. 为规则命名,例如 "Roles".
  8. Select "Active Directory" 作为 "Attribute Store".
  9. 在下面的table中,第一列输入select "Token-Groups Unqualified Names",第二列输入"roles"。

配置 OpenID Connect 以提供特定用户组作为声明

  1. 打开服务器管理器右上角 "Tools" 菜单下的 "AD FS Management" 工具。
  2. Select 左侧边栏中的 "Application Groups" 文件夹项。
  3. 双击之前添加的组,然后双击 "Web API" 应用程序。
  4. Select 名为 "Issuance Transform Rules" 的选项卡。
  5. 删除您可能已经添加的所有规则。
  6. 点击底部的"Add Rule..."按钮。
  7. Select"Send Claims Using a Custom Rule"点击下一步
  8. 将规则命名为 "StoreRoles" 并将以下内容粘贴到 "Custom rule" 字段中:
  9. 单击完成并添加另一个规则。
  10. 再次 select "Send Claims Using a Custom Rule" 然后单击下一步。
  11. 将此规则命名为 "IssueRoles" 并将以下内容粘贴到 "Custom rule" 字段中:
    • c:[Type == "roles", Value =~ "^Prefix.+"] => issue(claim = c);
  12. 包含 //"^Prefix.+"// 的部分是用于过滤作为声明的一部分发送的 windows 组的正则表达式。在这种情况下,我们只接受以 "Prefix" 开头的 windows 组。调整它以满足您的需要。
  13. 点击完成。

哇哦,经过 4 周的搜索、测试和调试,我终于在 ADFS4.0(AD FS 2019 服务器)上恢复了群组;

文档完全是废话所以,给你们。非常感谢@Max Fahl

  1. Create a Server Application
  2. Create a Web API
  3. Add the Client ID from step 1 as 'Relying party identifier' in the Web API
  4. Create the 3 rules Max described (Web API)
  5. Check 'Allatclaims, openid, profile' in Claims Permissions (Web API)

现在您可以使用 oAuth 通过 ADFS 对用户进行身份验证。

确保你使用这个;

        //Store state in session
        $state = uniqid("adfs-oauth");

        $params = [
            "client_id" => $this->adfs_config["client_id"],
            "response_type" => "code",
            "redirect_uri" => $this->adfs_config["redirect_uri"],
            "state" => $state,
            "response_mode" => "form_post",
        ];

然后用代码交换访问令牌;

"client_id" => $this->adfs_config["client_id"],
            "client_secret" => $this->adfs_config["client_secret"],
            "redirect_uri" => $this->adfs_config["redirect_uri"],
            "grant_type" => "authorization_code",
            "code" => $request->get("code")

现在您收到访问令牌、刷新令牌和ID_Token。

示例: ABCDABCDABCDABCDABCDABCDABCDABCD.ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD.ABCDABCDABCDABCDABCDABCD

用'.'分割令牌(点)。你现在有 3 个部分。第二部分包含信息(索引 1)。 Base 64 解码这个字符串,你得到 JSON 数据。

    array (
  'aud' => '53a****-8a5e-415b-**e4-37****65edd5',
  'iss' => 'https://*******.northeurope.cloudapp.azure.com/adfs',
  'iat' => 1623407419,
  'nbf' => 1623407419,
  'exp' => 1623411019,
  'auth_time' => 1623397846,
  'sub' => '**********************',
  'upn' => 'developer@developer.com',
  'unique_name' => 'ADFS_DOMAIN\developer',
  'sid' => 'S-1-5-21-******-3146660372-******-1112',
  'Roles' =>
  array (
    0 => 'Legal',
    1 => 'Administrator',
    2 => 'Users',
  ),
  'apptype' => 'Confidential',
  'appid' => '53a****-8a5e-415b-**e4-37****65edd5',
  'authmethod' => 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport',
  'ver' => '1.0',
)

使用此内容定义自定义规则以将所有组作为角色发送

c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"] => issue(store = "Active Directory", types = ("role"), query = ";tokenGroups(domainQualifiedName);{0}", param = c.Value);