【问题标题】:User groups as claims through OpenID Connect over ADFS通过 ADFS 上的 OpenID Connect 声明的用户组
【发布时间】:2019-08-24 22:26:53
【问题描述】:

在弄清楚如何通过 OpenID Connect over ADFS (Windows Server 2016) 获取用户分配的组时,我需要帮助。我目前能够对用户进行身份验证并获取包括 access_token 在内的用户信息。当我检查 JWT 令牌时,我可以在其中看到所有默认声明。我想要的是将所有用户分配的系统组作为字符串数组添加到声明中,但我不知道如何实现这一点。 ADFS 和 Windows Server 是一头野兽,谷歌的所有搜索结果都没有把我引向正确的方向。我发现的所有文章都有点没用,因为它们要么在步骤中不完整,要么如果你没有接受过整个 ADFS-shebang 的教育,就很难理解。

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

到目前为止我做了什么:

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

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

【问题讨论】:

    标签: openid-connect adfs


    【解决方案1】:

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

    先决条件

    为了能够执行以下步骤,您需要启用 Windows Server 2016 或更高版本并启用“Active Directory 联合身份验证服务 (ADFS)”功能。

    向 ADFS 添加 OpenID Connect 配置

    1. 打开位于服务器管理器右上角“工具”菜单下的“AD FS 管理”工具。
    2. 选择左侧边栏中的“应用程序组”文件夹项。
    3. 点击右侧边栏中的“添加应用程序组...”。
    4. 为应用程序组命名,例如“OpenID Connect”
    5. 选择“服务器应用程序访问 Web API”列表项,然后单击下一步。
    6. 客户端标识符复制并粘贴到文本文件中以供日后使用。
    7. 输入您的身份验证“重定向 URI”并单击下一步。
    8. 勾选“生成共享密钥”框。将 Secret 复制并粘贴到文本中以供您的应用程序使用。点击下一步。
    9. 粘贴并添加 客户端标识符(来自第 6 步)作为“标识符”。点击下一步。
    10. 选择您要使用的访问控制策略,然后单击下一步。
    11. 确保选中“openid”旁边的框。
    12. 单击底部的“新建范围...”按钮并将其命名为“allatclaims”,然后单击“确定”。需要此范围来提供作为声明的附加信息,例如用户组。
    13. 完成向导。

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

    1. 打开位于服务器管理器右上角“工具”菜单下的“AD FS 管理”工具。
    2. 选择左侧边栏中的“应用程序组”文件夹项。
    3. 双击之前添加的组,然后双击“Web API”应用程序。
    4. 选择名为“颁发转换规则”的选项卡。
    5. 点击底部的“添加规则...”按钮。
    6. 选择“将 LDAP 属性作为声明发送”,然后单击下一步。
    7. 为规则命名,例如“角色”。
    8. 选择“Active Directory”作为“属性存储”。
    9. 在下表的第一列中选​​择“Token-Groups Unqualified Names”,在第二列中输入“roles”。

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

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

    【讨论】:

    • 非常有帮助的帖子!
    • @Max Fahl,您需要对 oAuth 身份验证流程进行任何特定更改吗?我使用不同的流程、不同的设置进行了测试,但除了默认信息之外,我从未在 ID 令牌中得到任何不同的东西。
    【解决方案2】:

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

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

    1. 创建服务器应用程序
    2. 创建 Web API
    3. 将步骤 1 中的客户端 ID 添加为 Web API 中的“信赖方标识符”
    4. 创建 Max 描述的 3 条规则(Web API)
    5. 在 Claims Permissions (Web API) 中检查“Allatclaims、openid、profile”

    现在您可以使用 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

    用 '.' 分割 Token (点)。你现在有 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',
    )
    

    【讨论】:

      【解决方案3】:

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

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

      然后使用带有“令牌组”选项之一的 LDAP 规则,例如“不合格”并将其映射到“角色”类型。

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

      【讨论】:

      • 感谢您的回答!我在我的 Web API 应用程序的“颁发转换规则”选项卡中添加了从“令牌组 - 不合格名称”到“角色”的映射。我仍然看不到响应中的角色声明。我猜它应该在 access_token 数据中?我在这里能错过什么?我是否必须添加任何其他范围?问题是,我目前似乎无法获取用户的电子邮件或任何内容。
      • 似乎我没有将服务器应用程序的客户端 ID 正确添加到 Web API 中的“依赖方信任”中。现在它似乎正在工作:)
      【解决方案4】:

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

      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);

      【讨论】:

        猜你喜欢
        • 2016-05-19
        • 1970-01-01
        • 2022-01-12
        • 2013-12-02
        • 2018-05-08
        • 2020-07-09
        • 2016-10-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多