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

时间:2019-04-03 11:43:37

标签: openid-connect adfs

我需要帮助弄清楚如何通过ADFS(Windows Server 2016)上的OpenID Connect获取用户的分配组。我目前能够验证用户身份,并获取用户信息,包括access_token。当我检查JWT令牌时,可以在其中看到所有默认声明。我想要的是将所有用户分配的系统组作为字符串数组添加到声明中,但是我不知道如何实现此目的。 ADFS和Windows Server简直是野兽,来自Google的所有搜索结果都无法引导我朝正确的方向发展。我发现的所有文章都是没有用的,因为它们要么步骤不完整,要么如果您没有受过整个ADFS-shebang的教育,则很难遵循。

我已经在这个问题上停留了几天,需要一些帮助,希望那里有人对此有所了解。

到目前为止我所做的:

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

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

4 个答案:

答案 0 :(得分:2)

我们刚刚使所有工作正常进行,所以我想如果其他人想做我们所做的事情,我会分享我们所做的事情。

先决条件

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

将OpenID Connect配置添加到ADFS

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

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

  1. 打开服务器管理器右上方“工具”菜单下的“ AD FS管理”工具。
  2. 在左侧栏中选择“应用程序组”文件夹项。
  3. 双击先前添加的组,然后双击“ Web API”应用程序。
  4. 选择名为“签发转换规则”的标签。
  5. 单击底部的“添加规则...”按钮。
  6. 选择“将LDAP属性发送为声明”,然后单击下一步。
  7. 给规则起一个名字,例如“ Roles”。
  8. 选择“ Active Directory”作为“属性存储”。
  9. 在下表中,在第一列中选​​择“令牌组不合格名称”,然后在第二列中键入“角色”。

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

  1. 打开服务器管理器右上方“工具”菜单下的“ AD FS管理”工具。
  2. 在左侧栏中选择“应用程序组”文件夹项。
  3. 双击先前添加的组,然后双击“ Web API”应用程序。
  4. 选择名为“签发转换规则”的标签。
  5. 删除您可能已经添加的所有规则。
  6. 单击底部的“添加规则...”按钮。
  7. 选择“使用自定义规则发送声明”,然后单击下一步。
  8. 为规则指定名称“ StoreRoles”,并将以下内容粘贴到“自定义规则”字段中:
  9. 单击“完成”,然后添加另一个规则。
  10. 同样,选择“使用自定义规则发送声明”,然后单击下一步。
  11. 将此规则命名为“ IssueRoles”,并将以下内容粘贴到“自定义规则”字段中:
    • c:[类型==“角色”,值=〜“ ^前缀。+”] =>问题(声明= c);
  12. 包含//"^Prefix.+"//的部分是一个正则表达式,用于过滤作为声明的一部分发送的Windows组。在这种情况下,我们仅接受以“ Prefix”开头的Windows组。调整它以满足您的需求。
  13. 单击完成。

答案 1 :(得分:1)

哇哦,经过 4 周的搜索、测试和调试,我终于让组回到 ADFS4.0(AD FS 2019 服务器);

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

<块引用>
  1. 创建服务器应用程序
  2. 创建 Web API
  3. 将步骤 1 中的客户端 ID 添加为 Web API 中的“依赖方标识符”
  4. 创建 Max 描述的 3 条规则(Web API)
  5. 在声明权限 (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

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

答案 2 :(得分:0)

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

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

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

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

答案 3 :(得分: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);