首页 > 解决方案 > 为 ADFS 2019 (v4) 构建自定义身份验证方法

问题描述

我在 Windows Server 2019 上为 ADFS v4 创建自定义身份验证器时遇到问题。我的目标是创建自定义主身份验证器,但现在我愿意让自定义身份验证器作为附加身份验证提供程序工作。我关注了 Microsoft 的这篇文章,虽然它声明该教程适用于 2012 年,但它也应该适用于 2019 年。如果接下来的内容被视为意识流,我深表歉意,但我对此很陌生,并且我的实施可能有很多问题。

最初的挣扎

当我按照 Microsoft 的指示进行操作时,我可以在主要身份验证器列表中看到该身份验证器并选择它。但是,当我完成身份验证过程时,代码永远不会触发。我从未在项目中看到自定义 HTML 片段。如果我正确理解了此示例中的代码,我应该能够将身份验证器设置为主,并且只能从我的身份验证器获取 HTML。如果选择了多个主要身份验证器,我能做的最好的事情就是让友好的名称显示在可能的身份验证器列表中。

/// Returns a Dictionary containing the set of localized friendly names of the provider, indexed by lcid. 
     /// These Friendly Names are displayed in the "choice page" offered to the user when there is more than 
     /// one secondary authentication provider available.
     public Dictionary<int, string> FriendlyNames
     {
         get
         {
             Dictionary<int, string> _friendlyNames = new Dictionary<int, string>();
             _friendlyNames.Add(new CultureInfo("en-us").LCID, "Matt's Friendly name in the Meatadata Class");
             _friendlyNames.Add(new CultureInfo("fr").LCID, "Friendly name translated to fr locale");
             return _friendlyNames;
         }
     }

友好名称

如果我单击我的自定义身份验证器,它只会出错,并且我会在 ADFS 事件日志中获得一个条目,指出它找不到指定的用户。我认为通过使用自定义它会绕过任何 Active Directory 查找,但显然它仍在进行查找,而且我从来没有看到我的自定义登录页面。

然后我添加了日志记录

我将代码中的每个方法都记录到了 Windows 事件日志中,并且有一段时间我会收到一条消息,表明程序进入了 OnAuthenticationPipelineLoad 方法。

        public void OnAuthenticationPipelineLoad(IAuthenticationMethodConfigData configData)
        {
            //this is where AD FS passes us the config data, if such data was supplied at registration of the adapter
            myNewLog.WriteEntry("Matt -> this is where AD FS passes us the config data, if such data was supplied at registration of the adapter");

        }

不幸的是,这在某个时候停止了工作,我无法取回它,所以就像代码甚至不再到达这里一样。

微软的例子甚至不起作用

我在 GitHub 上四处寻找其他做过这件事的人,并找到了Microsoft 的示例提供程序。不幸的是,微软的代码也不起作用,所以它一定是我配置错了,但我不知道去哪里找。

然后我尝试将其设为辅助身份验证器

我尝试将我的自定义身份验证器设置为辅助,但在这种情况下代码也不会触发。

怀疑

在我的日志记录停止工作之前,我认为代码可能与 AuthenticationMethods 元数据存在问题。

        /// Returns an array of strings containing URIs indicating the set of authentication methods implemented by the adapter 
        /// AD FS requires that, if authentication is successful, the method actually employed will be returned by the
        /// final call to TryEndAuthentication(). If no authentication method is returned, or the method returned is not
        /// one of the methods listed in this property, the authentication attempt will fail.
        public virtual string[] AuthenticationMethods
        {
            get {
                myNewLog.WriteEntry("Matt -> AuthenticationMethods");

                return new[] { "https://example.com/myauthenticationmethod1" }; }
        }

我发现这可能是这里这里的问题的提示。它说“IAuthenticationAdapterMetadata:定义适配器元数据,包括其名称和它支持的身份验证类型”和“全局和依赖方 MFA AdditionalAuthenticationRules 声明规则集均已执行。(框 C)。如果任一输出声明集规则集包含类型为“http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod”的声明和值“http://schemas.microsoft.com/claims/multipleauthn”,然后是 MFA会参与。”

问题

我想我什至不知道我应该问什么作为我的问题。之前有没有人创建过自定义 ADFS 身份验证器并看到过这个问题?有什么明显的东西我可以检查可能导致这种情况吗?

标签: authenticationidentityserver4adfsidentityserver3adfs4.0

解决方案


结果证明这是一个由两部分组成的问题,并且是由于我缺乏领域知识而引起的。

辅助身份验证器修复

我将代码用作辅助身份验证器的问题与设置声明规则有关。这是本教程让我运行的 power shell 脚本:

Set-AdfsRelyingPartyTrust –TargetRelyingParty $rp –AdditionalAuthenticationRules 'c:[type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", value == "false"] => issue(type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", value = "http://schemas.microsoft.com/claims/multipleauthn" );'

我的问题是我是从我的网络内部而不是我的网络外部进行测试,所以脚本对我来说是错误的。一旦我编辑了规则以对内部用户强制执行 MFA,我的代码就成功命中。

Set-AdfsRelyingPartyTrust –TargetRelyingParty $rp –AdditionalAuthenticationRules 'c:[type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", value == "true"] => issue(type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", value = "http://schemas.microsoft.com/claims/multipleauthn" );'

主身份验证器修复

事实证明,我不能以我尝试的方式将我的代码用作主要身份验证器。ADFS 仅允许您针对 AD 身份提供者进行身份验证。ADFS 事件日志中的消息“找不到指定的用户”是试图绕过设置用户的步骤的结果。由于我不想为我的用户查询 Active Directory,因此我会收到一个错误,即身份验证器找不到指定的用户......这是有道理的。

我真正需要的是一个不同的身份提供者。对于我对 ADFS 的信赖方信任,我需要指定 Active Directory 以外的身份提供者。我在这里找到了一个例子。此解决方案使用托管在 asp.net 站点中的身份服务器 3作为身份提供者。通过使用此解决方案,我能够为当前用户手动设置声明。

此解决方案使用已过时的身份服务器 3,理想情况下您将使用当前支持的身份服务器 4。但是,身份服务器4的 ws-federation 部分已经移到了付费墙后面。

我的依赖方信任仍然存在问题,因为当用户从依赖方访问我们的站点时,他们会看到多个身份提供者(或 ADFS 所称的声明提供者)。为防止出现此屏幕,您可以将身份服务器设置为依赖方的默认声明提供者。

Set-AdfsRelyingPartyTrust -TargetName "Relying Party" -ClaimsProviderName ("IdentityServer")

补充笔记

关于身份服务器是什么以及它在这里试图解决的问题有一篇很好的文章

这里还有一个开源 repo 用于填写身份服务器 4 的 ws-federation 部分,我没有使用


推荐阅读