为 ADFS 2019 (v4) 构建自定义身份验证方法
Building Custom Authentication Method for ADFS 2019 (v4)
我在 Windows Server 2019 上为 ADFS v4 创建自定义身份验证器时遇到问题。我的目标是创建自定义主身份验证器,但现在我决定让自定义身份验证器作为额外的身份验证提供程序。我关注了 Microsoft 的 this 文章,虽然它声明该教程适用于 2012 年,但它也应该适用于 2019 年。如果接下来的内容是意识流,我深表歉意,但我对此还很陌生,我的实现可能有很多问题。
最初的挣扎
当我按照 Microsoft 的指示进行操作时,我能够在主要身份验证器列表中看到身份验证器并且 select 它。但是,当我完成身份验证过程时,代码永远不会触发。我从未在项目中看到自定义 HTML 片段。如果我正确理解此示例中的代码,我应该能够将身份验证器设置为主要和 only get the HTML from my authenticator。我能做的最好的事情就是让友好名称显示在可能的身份验证器列表中,如果超过一个主要身份验证器被 selected.
/// 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");
}
不幸的是,这在某个时候停止了工作,我无法取回它,所以好像代码甚至没有到这里。
Microsoft 的示例甚至不起作用
我搜索 GitHub 寻找其他做过这件事的人并找到了 Microsoft's example provider。不幸的是,微软的代码也不起作用所以它一定是我配置错误但我不知道在哪里看。
然后我尝试将其设为辅助身份验证器
我尝试将我的自定义身份验证器设置为次要身份验证器,但在这种情况下代码也不会触发。
怀疑
在我的日志记录停止工作之前,我认为代码可能与 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" }; }
}
我发现这可能是一个问题的提示 here and here。它说“IAuthenticationAdapterMetadata:定义适配器元数据,包括它的名称和它支持的身份验证类型”和“执行全局和依赖方 MFA AdditionalAuthenticationRules 声明规则集。(框 C)。如果输出声明集规则集包含类型为“http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod”和值为“http://schemas.microsoft.com/claims/multipleauthn”的声明,然后 MFA 将参与。
问题
我想我什至不知道我应该问什么作为我的问题。有没有人之前创建过自定义 ADFS 身份验证器并看到过这个问题?是否有明显的问题可供我检查是否是导致此问题的原因?
这原来是一个 two-part 问题,是由于我缺乏领域知识造成的。
辅助身份验证器修复
我将我的代码用作辅助身份验证器的问题与设置声明规则有关。这是教程给我的强大 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 以外的身份提供者。我找到了一个 here. This solution uses identity server 3 作为身份提供者托管在 asp.net 站点中的示例。通过使用此解决方案,我能够为当前用户手动设置声明。
此解决方案使用已过时的身份服务器 3,理想情况下您将使用当前支持的身份服务器 4。但是,identity server 4 的 ws-federation 部分已移至付费墙后面。
我的依赖方信任仍然存在问题,因为当用户从依赖方访问我们的站点时,它们会出现多个身份提供者(或 ADFS 称之为声明提供者)。为防止显示此屏幕,您可以将身份服务器设置为依赖方的默认声明提供者。
Set-AdfsRelyingPartyTrust -TargetName "Relying Party" -ClaimsProviderName ("IdentityServer")
补充说明
关于身份服务器是什么以及它试图解决的问题有一篇很好的文章here
还有一个开源存储库用于填写 ws-federation 身份服务器 4 here 的一部分,我没有使用
我在 Windows Server 2019 上为 ADFS v4 创建自定义身份验证器时遇到问题。我的目标是创建自定义主身份验证器,但现在我决定让自定义身份验证器作为额外的身份验证提供程序。我关注了 Microsoft 的 this 文章,虽然它声明该教程适用于 2012 年,但它也应该适用于 2019 年。如果接下来的内容是意识流,我深表歉意,但我对此还很陌生,我的实现可能有很多问题。
最初的挣扎
当我按照 Microsoft 的指示进行操作时,我能够在主要身份验证器列表中看到身份验证器并且 select 它。但是,当我完成身份验证过程时,代码永远不会触发。我从未在项目中看到自定义 HTML 片段。如果我正确理解此示例中的代码,我应该能够将身份验证器设置为主要和 only get the HTML from my authenticator。我能做的最好的事情就是让友好名称显示在可能的身份验证器列表中,如果超过一个主要身份验证器被 selected.
/// 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");
}
不幸的是,这在某个时候停止了工作,我无法取回它,所以好像代码甚至没有到这里。
Microsoft 的示例甚至不起作用
我搜索 GitHub 寻找其他做过这件事的人并找到了 Microsoft's example provider。不幸的是,微软的代码也不起作用所以它一定是我配置错误但我不知道在哪里看。
然后我尝试将其设为辅助身份验证器
我尝试将我的自定义身份验证器设置为次要身份验证器,但在这种情况下代码也不会触发。
怀疑
在我的日志记录停止工作之前,我认为代码可能与 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" }; }
}
我发现这可能是一个问题的提示 here and here。它说“IAuthenticationAdapterMetadata:定义适配器元数据,包括它的名称和它支持的身份验证类型”和“执行全局和依赖方 MFA AdditionalAuthenticationRules 声明规则集。(框 C)。如果输出声明集规则集包含类型为“http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod”和值为“http://schemas.microsoft.com/claims/multipleauthn”的声明,然后 MFA 将参与。
问题
我想我什至不知道我应该问什么作为我的问题。有没有人之前创建过自定义 ADFS 身份验证器并看到过这个问题?是否有明显的问题可供我检查是否是导致此问题的原因?
这原来是一个 two-part 问题,是由于我缺乏领域知识造成的。
辅助身份验证器修复
我将我的代码用作辅助身份验证器的问题与设置声明规则有关。这是教程给我的强大 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 以外的身份提供者。我找到了一个 here. This solution uses identity server 3 作为身份提供者托管在 asp.net 站点中的示例。通过使用此解决方案,我能够为当前用户手动设置声明。
此解决方案使用已过时的身份服务器 3,理想情况下您将使用当前支持的身份服务器 4。但是,identity server 4 的 ws-federation 部分已移至付费墙后面。
我的依赖方信任仍然存在问题,因为当用户从依赖方访问我们的站点时,它们会出现多个身份提供者(或 ADFS 称之为声明提供者)。为防止显示此屏幕,您可以将身份服务器设置为依赖方的默认声明提供者。
Set-AdfsRelyingPartyTrust -TargetName "Relying Party" -ClaimsProviderName ("IdentityServer")
补充说明
关于身份服务器是什么以及它试图解决的问题有一篇很好的文章here
还有一个开源存储库用于填写 ws-federation 身份服务器 4 here 的一部分,我没有使用