排查 Active Directory 联合身份验证服务 (AD FS) 的 SSO 问题

本文可帮助你解决 Active Directory 联合身份验证服务 (AD FS) 的单一登录 (SSO) 问题。

根据遇到的问题类型,选择以下部分之一。

适用范围:Active Directory 联合身份验证服务
原始 KB 编号: 4034932

NTLM 或基于表单的身份验证提示

在排查单一登录 (SSO) Active Directory 联合身份验证服务 (AD FS) 问题期间,如果用户收到意外的 NTLM 或基于表单的身份验证提示,请按照本文中的步骤排查此问题。

检查 Windows 集成身份验证设置

若要排查此问题,检查客户端浏览器中的 Windows 集成身份验证设置、AD FS 设置和身份验证请求参数。

检查用户的客户端浏览器

在 Internet 选项中检查以下设置:

  • 在“ 高级 ”选项卡上,确保已启用 “启用集成 Windows 身份验证” 设置。
  • 遵循 安全>本地 Intranet>站点>高级版,确保 AD FS URL 位于网站列表中。
  • 遵循 “安全 > 本地 Intranet > 自定义级别”,确保选中“ 仅在 Intranet 区域中自动登录 ”设置。

如果使用 Firefox、Chrome 或 Safari,请确保启用这些浏览器中的等效设置。

检查 AD FS 设置

检查 WindowsIntegratedFallback 设置
  1. 使用“以管理员身份运行”选项打开Windows PowerShell。

  2. 通过运行以下命令获取全局身份验证策略:

    Get-ADFSGlobalAuthenticationPolicy | fl WindowsIntegratedFallbackEnabled
    
  3. 检查 WindowsIntegratedFallbackEnabled 属性的值。

如果值为 True,则应该进行基于表单的身份验证。 这意味着身份验证请求来自不支持 Windows 集成身份验证的浏览器。 请参阅下一部分,了解如何支持浏览器。

如果值为 False,则应使用 Windows 集成身份验证。

检查 WIASupportedUsersAgents 设置
  1. 通过运行以下命令获取受支持的用户代理列表:

    Get-ADFSProperties | Select -ExpandProperty WIASupportedUserAgents
    
  2. 检查命令返回的用户代理字符串列表。

验证浏览器的用户代理字符串是否在列表中。 否则,请按照以下步骤添加用户代理字符串:

  1. 转到 http://useragentstring.com/ 检测并显示浏览器的用户代理字符串。

  2. 通过运行以下命令获取受支持的用户代理列表:

    $wiaStrings = Get-ADFSProperties | Select -ExpandProperty WIASupportedUserAgents
    
  3. 通过运行以下命令添加浏览器的用户代理字符串:

    $wiaStrings = $wiaStrings+"NewUAString"
    

    示例:

    $wiaStrings = $wiaStrings+" =~Windows\s*NT.*Edge"+"Mozilla/5.0"
    
  4. 运行以下命令,更新 WIASupportedUserAgents 设置:

    Set-ADFSProperties -WIASupportedUserAgents $wiaStrings
    

检查身份验证请求参数

检查身份验证请求是否将基于表单的身份验证指定为身份验证方法
  1. 如果身份验证请求是 WS-Federation 请求,检查请求是否包含 wauth= urn:oasis:names:tc:SAML:1.0:am:password
  2. 如果身份验证请求是 SAML 请求,检查如果请求包含值为 urn:oasis:names:tc:SAML:2.0:ac:classes:Password 的samlp:AuthnContextClassRef 元素。

有关详细信息,请参阅 AD FS 登录页的身份验证处理程序概述

检查应用程序是否为 Microsoft Online Services for Office 365

如果要访问的应用程序不是 Microsoft Online Services,则预期体验受传入身份验证请求控制。 请与应用程序所有者协作以更改行为。

注意

自 2024 年 3 月 30 日起,Azure AD 和 MSOnline PowerShell 模块已弃用。 若要了解详细信息,请阅读 弃用更新。 在此日期之后,对这些模块的支持仅限于 Microsoft Graph PowerShell SDK 和安全修补程序的迁移帮助。 弃用的模块将继续运行到 2025 年 3 月 30 日。

建议迁移到 Microsoft Graph PowerShell,以便与以前为 Azure AD) Microsoft Entra ID (交互。 有关常见的迁移问题,请参阅 迁移常见问题解答注意: MSOnline 1.0.x 版可能会在 2024 年 6 月 30 日之后遇到中断。

如果应用程序是 Microsoft Online Services,则你所体验的内容可能由受信任领域对象的 PromptLoginBehavior 设置控制。 此设置控制Microsoft Entra租户是否将 prompt=login 发送到 AD FS。 若要设置 PromptLoginBehavior 设置,请执行以下步骤:

  1. 使用“以管理员身份运行”选项打开Windows PowerShell。

  2. 通过运行以下命令获取现有域联合设置:

    Get-MSOLDomainFederationSettings -DomainName DomainName | FL *
    
  3. 通过运行以下命令设置 PromptLoginBehavior 设置:

    Set-MSOLDomainFederationSettings -DomainName DomainName -PromptLoginBehavior <TranslateToFreshPasswordAuth|NativeSupport|Disabled> -SupportsMFA <$TRUE|$FALSE> -PreferredAuthenticationProtocol <WsFed|SAMLP>
    

    PromptLoginBehavior 参数的值为:

    1. TranslateToFreshPasswordAuth:Microsoft Entra ID将 wauth 和 wfresh 发送到 AD FS,而不是 prompt=login。 这会导致身份验证请求使用基于表单的身份验证。
    2. NativeSupport:prompt=login 参数按原样发送到 AD FS。
    3. 已禁用:不向 AD FS 发送任何内容。

若要详细了解 Set-MSOLDomainFederationSettings 命令,请参阅 Active Directory 联合身份验证服务 prompt=login 参数支持

Microsoft Entra方案

如果发送到 Microsoft Entra ID的身份验证请求包含 prompt=login 参数,请运行以下命令禁用 prompt=login 功能:

Set-MsolDomainFederationSettings –DomainName DomainName -PromptLoginBehavior Disabled

运行此命令后,Office 365应用程序不会在每个身份验证请求中包含 prompt=login 参数。

非Microsoft Entra方案

身份验证请求中的请求参数(如 WAUTHRequestedAuthNContext) 可以指定身份验证方法。 检查其他请求参数是否强制执行意外身份验证提示。 如果是,请修改请求参数以使用预期的身份验证方法。

检查 SSO 是否已禁用

如果禁用 SSO,请启用它并测试问题是否已解决。

多重身份验证提示

若要解决此问题,检查信赖方中的声明规则是否正确设置为多重身份验证。

可以在 AD FS 服务器、信赖方或身份验证请求参数中指定多重身份验证。 检查配置,查看是否正确设置了这些配置。 如果预期需要多重身份验证,但系统反复提示你进行多重身份验证,检查信赖方颁发规则,以查看多重身份验证声明是否已传递到应用程序。

有关 AD FS 中的多重身份验证的详细信息,请参阅以下文章:

检查 AD FS 服务器和信赖方上的配置

若要检查 AD FS 服务器上的配置,请验证全局附加身份验证规则。 若要检查信赖方的配置,请验证信赖方信任的其他身份验证规则。

  1. 若要检查 AD FS 服务器上的配置,请在Windows PowerShell窗口中运行以下命令。

    Get-ADFSAdditionalAuthenticationRule
    

    若要在信赖方上检查配置,请运行以下命令:

    Get-ADFSRelyingPartyTrust -TargetName RelyingParty | Select -ExpandProperty AdditionalAuthenticationRules
    

    注意

    如果命令不返回任何内容,则不会配置其他身份验证规则。 跳过此部分。

  2. 观察配置的声明规则集。

验证声明规则集中是否启用了多重身份验证

声明规则集由以下部分组成:

  • 条件语句: C:[Type=``…,Value=…]
  • 问题声明: => issue (Type=``…,Value=…)

如果问题语句包含以下声明,则指定多重身份验证。
Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", Value = "http://schemas.microsoft.com/claims/multipleauthn"

下面是要求将多重身份验证分别用于未加入工作区的设备和 Extranet 访问的示例:

  • c:[Type == "http://schemas.microsoft.com/2012/01/devicecontext/claims/isregistereduser", Value == "false"] => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", Value = "http://schemas.microsoft.com/claims/multipleauthn")
  • 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")

检查信赖方颁发规则

如果用户在执行第一次身份验证后反复收到多重身份验证提示,则答复方可能未通过多重身份验证声明传递给应用程序。 若要检查是否通过身份验证声明,请执行以下步骤:

  1. 在 Windows PowerShell 中运行以下命令:

    Get-ADFSRelyingPartyTrust -TargetName ClaimApp
    
  2. 观察在 IssuanceAuthorizationRules 或 IssuanceAuthorizationRulesFile 属性中定义的规则集。

规则集应包含以下颁发规则,以通过多重身份验证声明:
C:[Type==http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod, Value==" http://schemas.microsoft.com/claims/multipleauthn"]=>issue(claim = c)

检查身份验证请求参数

检查身份验证请求是否将多重身份验证指定为身份验证方法

  • 如果身份验证请求是 WS-Federation 请求,检查如果请求包含 wauth= http://schemas.microsoft.com/claims/multipleauthn
  • 如果身份验证请求是 SAML 请求,检查请求是否包含值为 http://schemas.microsoft.com/claims/multipleauthnsamlp:AuthnContextClassRef 元素。

有关详细信息,请参阅 AD FS 登录页的身份验证处理程序概述

检查应用程序是否为 Microsoft Online Services for Office 365

如果要访问的应用程序是 Microsoft Online Services for Office 365,检查 SupportsMFA 域联合设置。

  1. 通过运行以下命令获取当前的 SupportsMFA 域联合设置:

    Get-MSOLDomainFederationSettings -DomainName DomainName | FL *
    
  2. 如果 SupportsMFA 设置为 FALSE,请运行以下命令将其设置为 TRUE:

    Set-MSOLDomainFederationSettings -DomainName DomainName -SupportsMFA $TRUE
    

检查 SSO 是否已禁用

如果禁用 SSO,请启用它并测试问题是否已解决。

用户无法登录目标站点或服务

此问题可能发生在 AD FS 登录页或应用程序端。

如果在 AD FS 登录页上出现此问题,则会收到“发生错误”、“HTTP 503 服务不可用”或其他一些错误消息。 错误页的 URL 显示 AD FS 服务名称,例如 fs.contoso.com

如果问题发生在应用程序端,则错误页的 URL 会显示目标服务的 IP 地址或站点名称。

根据遇到此问题的位置执行下一部分中的步骤。

此问题发生在 AD FS 登录页

若要排查此问题,检查所有用户是否都受到此问题的影响,以及用户是否可以访问所有信赖方。

所有用户都受到此问题的影响,并且用户无法访问任何信赖方

让我们使用 IdpInitiatedSignOn 检查内部登录功能。 为此,请使用 IdpInititatedSignOn 页验证 AD FS 服务是否已启动并运行,以及身份验证功能是否正常工作。 若要打开 IdpInitiatedSignOn 页,请执行以下步骤:

  1. 通过在 AD FS 服务器上运行以下命令,启用 IdpInitiatedSignOn 页:

    Set-AdfsProperties -EnableIdPInitiatedSignonPage $true
    
  2. 在网络中的计算机中,访问以下页面:
    https://<FederationInstance>/adfs/ls/idpinitiatedsignon.aspx

  3. 在登录页上输入有效用户的正确凭据。

登录成功

如果登录成功,检查 AD FS 服务状态是否正在运行。

  1. 在 AD FS 服务器上,打开服务器管理器。
  2. 在服务器管理器中,单击“工具>服务”。
  3. 检查Active Directory 联合身份验证服务的状态是否为“正在运行”。

然后,使用 IdpInitiatedSignOn 检查外部登录功能。 使用 IdpInititatedSignOn 页快速验证 AD FS 服务是否已启动并运行,以及身份验证功能是否正常工作。 若要打开 IdpInitiatedSignOn 页,请执行以下步骤:

  1. 通过在 AD FS 服务器上运行以下命令,启用 IdpInitiatedSignOn 页:

    Set-AdfsProperties -EnableIdPInitiatedSignonPage $true
    
  2. 在网络外部的计算机中,访问以下页面:
    https://<FederationInstance>/adfs/ls/idpinitiatedsignon.aspx

  3. 在登录页上输入有效用户的正确凭据。

如果登录失败,请参阅 检查 AD FS 相关组件和服务检查代理信任关系

如果登录成功,请继续按照 “所有用户受问题影响”中的步骤进行故障排除,并且用户可以访问某些信赖方

登录失败

如果登录失败,检查 AD FS 相关组件和服务

检查 AD FS 服务状态是否正在运行。

  1. 在 AD FS 服务器上,打开服务器管理器。
  2. 在服务器管理器中,单击“工具>服务”。
  3. 检查Active Directory 联合身份验证服务的状态是否为“正在运行”。

检查终结点是否已启用。 AD FS 为不同的功能和方案提供各种终结点。 默认情况下,并非所有终结点都处于启用状态。 若要检查终结点的状态,请执行以下步骤:

  1. 在 AD FS 服务器上,打开 AD FS 管理控制台。

  2. 展开 “服务>终结点”。

  3. 找到终结点,并验证状态是否在 “已启用” 列上启用。

    双检查启用所有 A D F S 终结点的状态。

然后,如果安装了 Microsoft Entra Connect,检查。 建议使用 Microsoft Entra Connect,这样可以简化 SSL 证书管理。

如果安装了 Microsoft Entra Connect,请确保使用它来管理和更新 SSL 证书

如果未安装 Microsoft Entra Connect,检查 SSL 证书是否满足以下 AD FS 要求:

  • 证书来自受信任的根证书颁发机构。

    AD FS 要求 SSL 证书来自受信任的根证书颁发机构。 如果从未加入域的计算机访问 AD FS,建议使用来自 DigiCert、VeriSign 等受信任第三方根证书颁发机构的 SSL 证书。如果 SSL 证书不是来自受信任的根证书颁发机构,则 SSL 通信可能会中断。

  • 证书的使用者名称有效。

    使用者名称应与联合身份验证服务名称匹配,而不是 AD FS 服务器名称或其他名称。 若要获取联合身份验证服务名称,请在主 AD FS 服务器上运行以下命令:
    Get-AdfsProperties | select hostname

  • 不会吊销证书。

    检查证书吊销。 如果证书被吊销,则 SSL 连接将不受信任,客户端将阻止 SSL 连接。

如果 SSL 证书不符合这些要求,请尝试获取用于 SSL 通信的合格证书。 建议使用 Microsoft Entra Connect,这样可以简化 SSL 证书管理。 请参阅更新Active Directory 联合身份验证服务 (AD FS) 场的 TLS/SSL 证书

如果 SSL 证书满足这些要求,检查 SSL 证书的以下配置。

检查 SSL 证书是否已正确安装

SSL 证书应安装到场中每个联合服务器上的本地计算机的 个人 存储中。 若要安装证书,请双击 。证书的 PFX 文件,并按照向导进行操作。

若要验证证书是否已安装到正确位置,请执行以下步骤:

  1. 运行以下命令,列出本地计算机 的个人 存储中的证书:
    dir Cert:\LocalMachine\My
  2. 检查证书是否在列表中。
检查是否正在使用正确的 SSL 证书

获取用于 SSL 通信的证书的指纹,并验证指纹是否与预期的证书指纹匹配。

若要获取正在使用的证书的指纹,请在 Windows PowerShell 中运行以下命令:

Get-AdfsSslCertificate

如果使用了错误的证书,请运行以下命令来设置正确的证书:

Set-AdfsSslCertificate –Thumbprint CorrectThumprint
检查 SSL 证书是否设置为服务通信证书

SSL 证书需要设置为 AD FS 场中的服务通信证书。 这不会自动发生。 若要检查是否设置了正确的证书,请执行以下步骤:

  1. 在 AD FS 管理控制台中,展开 “服务>证书”。
  2. 验证 “服务通信 ”下列出的证书是否为预期的证书。

如果列出了错误的证书,请设置正确的证书,然后向 AD FS 服务授予对证书的 “读取 ”权限。 为此,请按照下列步骤操作:

  1. 设置正确的证书:

    1. 右键单击“ 证书”,然后单击“ 设置服务通信证书”。
    2. 选择正确的证书。
  2. 验证 AD FS 服务是否对证书具有 读取 权限:

    1. 将本地计算机帐户的 “证书” 管理单元添加到 Microsoft 管理控制台 (MMC) 。
    2. 展开“证书(本地计算机)”>“个人”>“证书”
    3. 右键单击 SSL 证书,单击“ 所有任务>管理私钥”。
    4. 验证 adfssrv 是否在 “组和用户名” 下列出,并具有 “读取 ”权限。
  3. 如果未列出 adfssrv,请向 AD FS 服务授予对证书的 “读取 ”权限:

    1. 依次单击“ 添加”、“ 位置”、“服务器”和“ 确定”。
    2. “输入要选择的对象名称”下,输入 nt service\adfssrv,单击“ 检查名称”,然后单击“ 确定”。
      如果将 AD FS 与设备注册服务 (DRS) 配合使用,请改为输入 nt service\drs
    3. 授予 “读取 ”权限,然后单击“ 确定”。
检查是否在 AD FS 中配置了设备注册服务 (DRS)

如果已使用 DRS 配置 AD FS,请确保也为 RDS 正确配置了 SSL 证书。 例如,如果有两个 UPN 后缀 contoso.comfabrikam.com,则证书必须具有 enterpriseregistration.contoso.comenterpriseregistration.fabrikma.com ,因为 SAN) (使用者可选名称。

若要检查 SSL 证书是否具有正确的 SAN,请执行以下步骤:

  1. 通过运行以下命令列出组织中使用的所有 UPN 后缀:

    Get-AdfsDeviceRegistratrionUpnSuffix
    
  2. 验证 SSL 证书是否配置了所需的 SAN。

  3. 如果 SSL 证书没有正确的 DRS 名称作为 SAN,请获取具有正确 DRS SAN 的新 SSL 证书,然后将其用作 AD FS 的 SSL 证书。

然后,检查 WAP 服务器上的证书配置和回退绑定:

  • 检查是否在所有 WAP 服务器上设置了正确的 SSL 证书。

    1. 确保 SSL 证书安装在每个 WAP 服务器上的本地计算机的 个人 存储中。

    2. 通过运行以下命令获取 WAP 使用的 SSL 证书:

      Get-WebApplicationProxySslCertificate
      
    3. 如果 SSL 证书错误,请运行以下命令设置正确的 SSL 证书:

      Set-WebApplicationProxySslCertificate -Thumbprint Thumbprint
      
  • 检查证书绑定并在必要时更新它们。

    若要支持非 SNI 案例,管理员可以指定回退绑定。 除标准 federationservicename:443 绑定外,请在以下应用程序 ID 下查找回退绑定:

    • {5d89a20c-beab-4389-9447-324788eb944a}:这是 AD FS 的应用程序 ID。
    • {f955c070-e044-456c-ac00-e9e4275b3f04}:这是 Web 应用程序代理的应用程序 ID。

    例如,如果为 0.0.0.0:443 等回退绑定指定了 SSL 证书,请确保在更新 SSL 证书时相应地更新绑定。

所有用户都受此问题影响,用户可以访问某些信赖方

首先,获取信赖方和 OAuth 客户端信息。 如果使用传统的信赖方,请执行以下步骤:

  1. 在主 AD FS 服务器上,使用“以管理员身份运行”选项打开Windows PowerShell。

  2. 运行以下命令,将 AD FS 2.0 组件添加到Windows PowerShell:

    Add-PSSnapin Microsoft.Adfs.PowerShell
    
  3. 通过运行以下命令获取信赖方信息:

    $rp = Get-AdfsRelyingPartyTrust RPName
    
  4. 通过运行以下命令获取 OAuth 客户端信息:

    $client = Get-AdfsClient ClientName
    

如果在 Windows Server 2016 中使用应用程序组功能,请执行以下步骤:

  1. 在主 AD FS 服务器上,使用“以管理员身份运行”选项打开Windows PowerShell。

  2. 通过运行以下命令获取信赖方信息:
    $rp = Get-AdfsWebApiApplication ResourceID

  3. 如果 OAuth 客户端是公共的,请运行以下命令获取客户端信息:

    $client = Get-AdfsNativeClientApplication ClientName
    

    如果客户端是机密的,请运行以下命令获取客户端信息:

    $client = Get-AdfsServerApplication ClientName
    

现在,请继续使用以下故障排除方法。

检查信赖方和客户端的设置

信赖方标识符、客户端 ID 和重定向 URI 应由应用程序和客户端的所有者提供。 但是,所有者提供的内容与 AD FS 中的配置之间仍可能存在不匹配的情况。 例如,不匹配可能是由拼写错误引起的。 检查所有者提供的设置是否与 AD FS 中配置的设置匹配。 上一页中的步骤通过 PowerShell 获取 AD FS 中配置的设置。

所有者提供的设置 在 AD FS 中配置的设置
信赖方 ID $rp。标识符
信赖方重定向 URI 的前缀或通配符匹配项
  • $rp。WS-Fed 信赖方的 WSFedEndpoint
  • $rp。SAML 信赖方的 SamlEndpoints
客户端 ID $client。ClientId
客户端重定向 URI $client的前缀匹配。RedirectUri

如果表中的项匹配,则另外检查这些设置在发送到 AD FS 的身份验证请求中显示的内容与 AD FS 中配置的内容是否匹配。 尝试重现在应用程序发送到 AD FS 的身份验证请求上捕获 Fiddler 跟踪的问题。 检查请求参数以根据请求类型执行以下检查。

OAuth 请求

OAuth 请求如下所示:

https://sts.contoso.com/adfs/oauth2/authorize?response_type=code&client_id=ClientID&redirect_uri=https://www.TestApp.com&resource=https://www.TestApp.com

检查请求参数是否与 AD FS 中配置的设置匹配。

请求参数 在 AD FS 中配置的设置
client_id $client。ClientId
redirect_uri 前缀匹配项 @client_RedirectUri

“resource”参数应表示 AD FS 中的有效信赖方。 通过运行以下命令之一获取信赖方信息。

  • 如果使用传统的信赖方,请运行以下命令:
    Get-AdfsRelyingPartyTrust -Identifier "ValueOfTheResourceParameter"
  • 如果在 Windows Server 2016 中使用应用程序组功能,请运行以下命令:
    Get-AdfsWebApiApplication "ValueOfTheResourceParameter"
WS-Fed 请求

WS-Fed 请求如下所示:

https://fs.contoso.com/adfs/ls/?wa=wsignin1.0&wtrealm=https://claimsweb.contoso.com&wctx=rm=0&id=passive&ru=/&wct=2014-10-21T22:15:42Z

检查请求参数是否与 AD FS 中配置的设置匹配:

请求参数 在 AD FS 中配置的设置
wtrealm $rp。标识符
wreply $rp的前缀匹配或通配符匹配。WSFedEndpoint
SAML 请求

SAML 请求如下所示:

https://sts.contoso.com/adfs/ls/?SAMLRequest=EncodedValue&RelayState=cookie:29002348&SigAlg=http://www.w3.org/2000/09/Fxmldsig#rsa-sha1&Signature=Signature

使用 Fiddler 文本向导中的“From DeflatedSAML”选项解码 SAMLRequest 参数的值。 解码的值如下所示:

<samlp:AuthnRequest ID="ID" Version="2.0" IssueInstant="2017-04-28T01:02:22.664Z" Destination="https://TestClaimProvider-Samlp-Only/adfs/ls" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" ForceAuthn="true" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://fs.contoso.com/adfs/services/trust</Issuer><samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" AllowCreate="true" /></samlp:AuthnRequest>

在解码值内执行以下检查:

  • 检查“目标”值中的主机名是否与 AD FS 主机名匹配。
  • 检查颁发者的值是否与 匹配 $rp.Identifier

有关 SAML 的其他说明:

  • $rp。SamlEndpoints:显示所有类型的 SAML 终结点。 AD FS 的响应将发送到终结点中配置的相应 URL。 SAML 终结点可以使用重定向、发布或项目绑定进行消息传输。 所有这些 URL 都可以在 AD FS 中配置。
  • $rp。SignedSamlRequestsRequired:如果设置了该值,则需要对从信赖方发送的 SAML 请求进行签名。 请求中需要存在“SigAlg”和“Signature”参数。
  • $rp。RequestSigningCertificate:这是用于在 SAML 请求上生成签名的签名证书。 确保证书有效,并要求应用程序所有者匹配证书。
检查加密证书

如果 $rp.EncryptClaims 返回 Enabled,则启用信赖方加密。 AD FS 使用加密证书来加密声明。 执行以下检查:

  • $rp。EncryptionCertificate:使用此命令获取证书并检查证书(如果有效)。
  • $rp。 EncryptionCertificateRevocationCheck:如果证书满足吊销检查要求,请使用此命令检查。
前两种方法不起作用

若要继续故障排除,请参阅 使用转储令牌应用

并非所有用户都受到此问题的影响,并且用户无法访问任何信赖方

在此方案中,执行以下检查。

检查用户是否已禁用

在Windows PowerShell或 UI 中检查用户状态。 如果用户被禁用,请启用该用户。

使用Windows PowerShell检查用户状态
  1. 登录到任何域控制器。

  2. 打开 Windows PowerShell。

  3. 运行以下命令,检查用户状态:

    Get-ADUser -Identity <samaccountname of the user> | Select Enabled
    

    使用 Get-ADUser 命令检查用户启用状态。

在 UI 中检查用户状态
  1. 登录到任何域控制器。

  2. 打开Active Directory 用户和计算机管理控制台。

  3. 单击“ 用户” 节点,在右窗格中右键单击该用户,然后单击“ 属性”。

  4. 单击“ 帐户 ”选项卡。

  5. “帐户选项”下,验证是否已选中 “帐户已禁用 ”。

    双重检查是否选中“帐户已禁用”选项。

  6. 如果选中了选项,请取消选中它。

检查用户属性最近是否已更新

如果在 Active Directory 中更新了用户的任何属性,则会导致用户对象的元数据发生更改。 检查用户元数据对象,查看最近更新的属性。 如果找到更改,请确保相关服务会选取这些更改。 若要检查用户是否有属性更改,请执行以下步骤:

  1. 登录到域控制器。

  2. 打开 Windows PowerShell。

  3. 通过运行以下命令获取用户对象的元数据:
    repadmin /showobjmeta <destination DC> "user DN"

    命令的一个示例是:
    repadmin /showobjmeta localhost "CN=test user,CN=Users,DC=fabidentity,DC=com"

  4. 在元数据中,检查每个属性的“时间/日期”列是否有任何更改线索。 在以下示例中,userPrincipleName 属性采用的日期比其他属性(表示对用户对象元数据的更改)更新。

    repadmin showobjmeta 命令的输出。

检查用户是否属于另一个林的林信任

在多林 AD FS 环境中,部署 AD FS 的林和其他利用 AD FS 部署进行身份验证的林之间需要双向林信任。 若要验证林之间的信任是否按预期工作,请执行以下步骤:

  1. 登录到部署了 AD FS 的林中的域控制器。

  2. 打开 Active Directory 域和信任管理控制台。

  3. 在管理控制台中,右键单击包含要验证的信任的域,然后单击“属性”。

  4. 单击“ 信任 ”选项卡。

  5. 在“ 此域信任的域 (传出信任) 信任此域 (传入信任) 的域 ”下,单击要验证的信任,然后单击“ 属性”。

  6. 单击“ 验证”。
    “Active Directory 域服务”对话框中,选择任一选项。

    • 如果选择“ ”,建议对倒数域重复相同的过程。

    • 如果选择“ ”,请为互惠域提供管理用户凭据。 无需对倒数域执行相同的过程。

      在“Active Directory 域服务”对话框中验证传入的信任。

如果这些步骤无法帮助你解决问题,请继续执行故障排除,并按照 并非所有用户都受问题影响中的步骤进行故障排除,并且用户可以访问某些信赖方 部分。

并非所有用户都受到此问题的影响,并且用户可以访问某些信赖方

在此方案中,检查此问题是否发生在Microsoft Entra方案中。 如果是这样,请执行这些检查来排查此问题。 如果没有,请参阅 使用转储令牌应用 来排查此问题。

检查用户是否已同步到Microsoft Entra ID

如果用户尝试登录到 Microsoft Entra ID,则会将其重定向到 AD FS,以便对联合域进行身份验证。 登录失败的可能原因之一是用户尚未同步到Microsoft Entra ID。 在 AD FS 进行第一次身份验证尝试后,你可能会看到从 Microsoft Entra ID 到 Active Directory FS 的循环。 若要确定是否将用户同步到Microsoft Entra ID,请执行以下步骤:

  1. 下载并安装用于Windows PowerShell的 Azure AD PowerShell 模块。
  2. 使用“以管理员身份运行”选项打开Windows PowerShell。
  3. 通过运行以下命令启动与 Microsoft Entra ID 的连接:
    Connect-MsolService
  4. 提供连接的全局管理员凭据。
  5. 通过运行以下命令获取Microsoft Entra ID中的用户列表:
    Get-MsolUser
  6. 验证用户是否在列表中。

如果用户不在列表中,请将用户同步到Microsoft Entra ID。

检查颁发声明规则中的 immutableID 和 UPN

Microsoft Entra ID要求 immutableID 和用户的 UPN 对用户进行身份验证。

注意

在以下工具中,immutableID 也称为 sourceAnchor:

  • Azure AD Sync
  • Azure Active Directory 同步 (DirSync)

管理员可以使用 Microsoft Entra Connect 通过 Microsoft Entra ID 自动管理 AD FS 信任。 如果不通过 Microsoft Entra Connect 管理信任,我们建议通过下载 Microsoft Entra Connect Microsoft Entra Connect 启用基于同步设置的自动声明规则管理来执行此操作。

若要检查 AD FS 中 immutableID 和 UPN 的声明规则是否与Microsoft Entra ID使用的内容匹配,请执行以下步骤:

  1. 在 Microsoft Entra Connect 中获取 sourceAnchor 和 UPN。

    1. 打开 Microsoft Entra Connect。

    2. 单击“ 查看当前配置”。

      在“Microsoft Entra连接其他任务”页中选择“查看当前配置”。

    3. 在“ 查看解决方案 ”页上,记下 “源定位点 ”和 “用户主体名称”的值

  2. 验证 ad FS 服务器中配置的相应声明规则中 (sourceAnchor) 和 UPN 的 immutableID 的值。

    1. 在 AD FS 服务器上,打开 AD FS 管理控制台。

    2. 单击“ 信赖方信任”。

    3. 右键单击具有Microsoft Entra ID的信赖方信任,然后单击“编辑声明颁发策略”。

    4. 打开不可变 ID 和 UPN 的声明规则。

    5. 验证为 immutableID 和 UPN 值查询的变量是否与 Microsoft Entra Connect 中显示的变量相同。

      验证 A D F S 服务器中配置的相应声明规则中 immutableID 和 UPN 的值。

  3. 如果存在差异,请使用以下方法之一:

    • 如果 AD FS 由 Microsoft Entra Connect 管理,请使用 Microsoft Entra Connect 重置信赖方信任。
    • 如果 AD FS 不是由 Microsoft Entra Connect 管理,请使用正确的属性更正声明。

如果这些检查无法解决问题,请参阅 使用转储令牌应用 来排查此问题。

应用程序端出现此问题

如果令牌签名证书最近由 AD FS 续订,检查联合合作伙伴是否选取了新证书。 如果 AD FS 使用最近也续订的令牌解密证书,也执行相同的检查。 若要检查 AD FS 上的当前 AD FS 令牌签名证书是否与联合身份验证合作伙伴上的证书匹配,请执行以下步骤:

  1. 运行以下命令,获取 AD FS 上的当前令牌签名证书:

    Get-ADFSCertificate -CertificateType token-signing
    
  2. 在返回的证书列表中,找到 IsPrimary = TRUE 的证书,并记下指纹。

  3. 获取联合合作伙伴上当前令牌签名证书的指纹。 应用程序所有者需要提供此信息。

  4. 比较两个证书的指纹。

如果 AD FS 使用续订的令牌解密证书,则执行相同的检查,但用于在 AD FS 上获取令牌解密证书的命令如下所示:

Get-ADFSCertificate -CertificateType token-decrypting

两个证书的指纹匹配

如果指纹匹配,请确保合作伙伴使用新的 AD FS 证书。

如果证书不匹配,请确保合作伙伴使用的是新证书。 证书包含在 AD FS 服务器发布的联合元数据中。

注意

合作伙伴是指所有资源组织或帐户组织合作伙伴,这些合作伙伴通过信赖方信任和声明提供程序信任在 AD FS 中表示。

  • 合作伙伴可以访问联合元数据

    如果合作伙伴可以访问联合元数据,请要求合作伙伴使用新证书。

  • 合作伙伴无法访问联合元数据

    在这种情况下,必须手动向合作伙伴发送新证书的公钥。 为此,请按照下列步骤操作:

    1. 将公钥导出为 .cert 文件或 .p7b 文件,以包含整个证书链。
    2. 将公钥发送给合作伙伴。
    3. 要求合作伙伴使用新证书。

两个证书的指纹不匹配

然后,检查是否存在令牌签名算法不匹配的情况。 为此,请按照下列步骤操作:

  1. 通过运行以下命令确定信赖方使用的算法:

    Get-ADFSRelyingPartyTrust -Name RPName | FL SignatureAlgorithm
    

    可能的值为 SHA1 或 SHA256。

  2. 请与应用程序所有者联系,了解在应用程序端使用的算法。

  3. 检查两种算法是否匹配。

如果这两种算法匹配,检查名称 ID 格式是否与应用程序所需的格式匹配。

  1. 在 AD FS 服务器上,通过运行以下命令转储颁发转换规则:

    (Get-AdfsRelyingPartyTrust -Name RPName).IssuanceTransformRules
    
  2. 找到发出 NameIdentifier 声明的规则。 如果此类规则不存在,请跳过此步骤。

    下面是规则的示例:

    c:[Type == "http://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableID"] => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Value = c.Value, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified");

    请注意以下语法中的 NameIdentifier 格式:

    Properties["Property-type-URI"] = "ValueURI"

    下面列出了可能的格式。 第一种格式是默认格式。

    • urn:oasis:names:tc:SAML:1.1:nameid-format:unspecifie。
    • urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
    • urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
    • urn:oasis:names:tc:SAML:2.0:nameid-format:transient
  3. 向应用程序所有者询问应用程序所需的 NameIdentifier 格式。

  4. 验证两种 NameIdentifier 格式是否匹配。

  5. 如果格式不匹配,请将 NameIdentifier 声明配置为使用应用程序所需的格式。 为此,请按照下列步骤操作:

    1. 打开 AD FS 管理控制台。
    2. 单击“信赖方信任”,选择适当的联合合作伙伴,然后在“操作”窗格中单击“编辑声明颁发策略”。
    3. 如果没有用于颁发 NameIdentifier 声明或更新现有规则的规则,请添加新规则。 为“传入声明类型”选择“名称 ID”,然后指定应用程序所需的格式。

    如果没有用于颁发 NameIdentifier 声明或更新现有规则的规则,则添加转换声明规则。

如果两种算法不匹配,请更新信赖方信任使用的签名算法。

  1. 打开 AD FS 管理控制台。

  2. 右键单击信赖方信任,然后单击“ 属性”。

  3. 在“ 高级 ”选项卡上,选择与应用程序所需的算法匹配。

    在“属性设置”对话框中的“高级”选项卡下,选择与应用程序所需的算法相匹配。

关于证书自动续订

如果令牌签名证书或令牌解密证书是自签名证书,则默认在这些证书上启用 AutoCertificateRollover,并且 AD FS 会在证书即将过期时管理证书的自动续订。

若要确定是否使用自签名证书,请执行以下步骤:

  1. 运行以下命令:

    Get-ADFSCerticate -CertificateType "token-signing"
    

    运行 Get-ADFSCerticate cmdlet 证书类型令牌签名。

  2. 检查证书属性。

    如果 Subject 和 Issuer 属性都以“CN=ADFS 签名...”开头,则证书是自签名的,由 AutoCertRollover 管理。

若要确认证书是否自动续订,请执行以下步骤:

  1. 运行以下命令:

    Get-ADFSProperties | FL AutoCertificateRollover
    

    运行 Get-ADFSProperties cmdlet 以确认证书是否自动续订。

  2. 检查 AutoCertificateRollover 属性。

    • 如果 AutoCertificateRollover = TRUE,则默认情况下,AD FS 会在过期前 (30 天自动生成新证书) ,并在过期) 前 25 天将其设置为主证书 (。
    • 如果 AutoCertificateRollover = FALSE,则需要手动替换证书。

本文介绍如何检查与 ADFS 相关的组件和服务。 排查 Active Directory 联合身份验证服务 (ADFS) 的登录 (SSO) 问题时,这些步骤可能会有所帮助。

检查 DNS

访问 ADFS 应直接指向 WAP (Web 应用程序代理) 服务器或 WAP 服务器前面的负载均衡器之一。 执行以下检查:

  • ping 联合身份验证服务名称 (例如 fs.contoso.com) 。 确认 Ping 解析为的 IP 地址是 WAP 服务器之一还是 WAP 服务器的负载均衡器。
  • 检查 DNS 服务器中是否存在联合身份验证服务的 A 记录。 A 记录应指向 WAP 服务器之一或 WAP 服务器的负载均衡器。

如果在外部访问的方案中未实现 WAP,检查如果访问 ADFS 直接指向 ADFS 服务器之一或 ADFS 服务器前面的负载均衡器:

  • ping 联合身份验证服务名称 (例如 fs.contoso.com) 。 确认获取的 IP 地址是解析为 ADFS 服务器之一还是 ADFS 服务器的负载均衡器。
  • 检查 DNS 服务器中是否存在联合身份验证服务的 A 记录。 A 记录应指向其中一个 ADFS 服务器或 ADFS 服务器的负载均衡器。

检查负载均衡器是否已使用

检查防火墙是否阻止了以下之间的流量:

  • ADFS 服务器和负载均衡器。
  • WAP (Web 应用程序代理) 服务器和负载均衡器(如果使用 WAP)。

如果在负载均衡器上启用了探测,检查以下内容:

  • 如果运行的是 R2 Windows Server 2012,请确保已安装 2014 年 8 月更新汇总
  • 检查 WAP 服务器和 ADFS 服务器上的防火墙中是否启用了端口 80。
  • 确保为端口 80 和终结点 /adfs/probe 设置了探测。

检查防火墙设置

检查是否在上启用了通过 TCP 端口 443 的入站流量:

  • Web 应用程序代理 服务器与联合服务器场之间的防火墙。
  • 客户端与 Web 应用程序代理 服务器之间的防火墙。

如果满足以下条件,请检查客户端与 Web 应用程序代理 服务器之间的防火墙上是否启用了通过 TCP 端口 49443 的入站流量:

  • 已启用使用 X.509 证书的 TLS 客户端身份验证。
  • 你在 Windows Server 2012 R2 上使用 ADFS。

注意

Web 应用程序代理 服务器与联合服务器之间的防火墙不需要配置。

检查代理上是否启用了终结点

ADFS 为不同的功能和方案提供各种终结点。 默认情况下,并非所有终结点都处于启用状态。 若要检查代理上是否启用了终结点,请执行以下步骤:

  1. 在 ADFS 服务器上,打开 ADFS 管理控制台。

  2. 展开 “服务>终结点”。

  3. 找到终结点,并在“ 已启用代理 ”列上验证状态是否已启用。

    验证“已启用代理”列上显示的 A D F S 终结点状态。

检查代理信任关系

如果部署了 Web 应用程序代理 (WAP) ,则必须在 WAP 服务器和 AD FS 服务器之间建立代理信任关系。 检查代理信任关系是否已建立或在某些时间点开始失败。

注意

此页上的信息适用于 AD FS 2012 R2 及更高版本。

背景信息

代理信任关系基于客户端证书。 运行 Web 应用程序代理安装后向导时,向导将使用向导中指定的凭据生成自签名客户端证书。 然后,向导将证书插入 AD FS 配置数据库中,并将其添加到 AD FS 服务器上的 AdfsTrustedDevices 证书存储中。

对于任何 SSL 通信,http.sys 使用以下 SSL 证书绑定优先级顺序来匹配证书:

优先级 名称 参数 说明
1 IP IP:port 确切的 IP 和端口匹配
2 SNI Hostname:port 确切的主机名匹配 (连接必须指定 SNI)
3 Ccs 端口 调用中央证书存储区
4 IPv6 通配符 端口 IPv6 通配符匹配 (连接必须为 IPv6)
5 IP 通配符 端口 IP 通配符匹配 (连接可以是 IPv4 或 IPv6)

AD FS 2012 R2 及更高版本独立于 Internet Information Services (IIS) ,并在 http.sys 之上作为服务运行。 hostname:port SSL 证书绑定由 AD FS 使用。 在客户端证书身份验证期间,AD FS 根据 AdfsTrustedDevices 存储中的证书 (CTL) 发送证书信任列表。 如果 AD FS 服务器的 SSL 证书绑定使用 IP:端口或 CTL 存储不是 AdfsTrustedDevices,则可能无法建立代理信任关系。

获取 AD FS 的 SSL 证书绑定

在 AD FS 服务器上,在 Windows PowerShell 中运行以下命令:
netsh http show sslcert

在返回的绑定列表中,查找应用程序 ID 为 5d89a20c-beab-4389-9447-324788eb944a 的绑定。 下面是正常绑定的示例。 记下“Ctl Store 名称”行。

Hostname:port : adfs.contoso.com:443
Certificate Hash : 3638de9b03a488341dfe32fc3ae5c480ee687793
Application ID : {5d89a20c-beab-4389-9447-324788eb944a}
Certificate Store Name : MY
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)  
Ctl Store Name : AdfsTrustedDevices
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled

运行脚本以自动检测问题

若要自动检测代理信任关系的问题,请运行以下脚本。 根据检测到的问题,相应地执行操作。

param
(
  [switch]$syncproxytrustcerts
)
function checkhttpsyscertbindings()
{
Write-Host; Write-Host("1 – Checking http.sys certificate bindings for potential issues")
$httpsslcertoutput = netsh http show sslcert
$adfsservicefqdn = (Get-AdfsProperties).HostName
$i = 1
$certbindingissuedetected = $false
While($i -lt $httpsslcertoutput.count)
{
        $ipport = $false
        $hostnameport = $false
        if ( ( $httpsslcertoutput[$i] -match "IP:port" ) ) { $ipport = $true }
        elseif ( ( $httpsslcertoutput[$i] -match "Hostname:port" ) ) { $hostnameport = $true }
        ## Check for IP specific certificate bindings
        if ( ( $ipport -eq $true ) )
        {
            $httpsslcertoutput[$i]
            $ipbindingparsed = $httpsslcertoutput[$i].split(":")
            if ( ( $ipbindingparsed[2].trim() -ne "0.0.0.0" ) -and ( $ipbindingparsed[3].trim() -eq "443") )
            {
                $warning = "There is an IP specific binding on IP " + $ipbindingparsed[2].trim() + " which may conflict with the AD FS port 443 cert binding." | Write-Warning
                $certbindingissuedetected = $true
            }
            $i = $i + 14
            continue
        }
        ## check that CTL Store is set for ADFS service binding
        elseif ( $hostnameport -eq $true )
        {
            $httpsslcertoutput[$i]
            $ipbindingparsed = $httpsslcertoutput[$i].split(":")
            If ( ( $ipbindingparsed[2].trim() -eq $adfsservicefqdn ) -and ( $ipbindingparsed[3].trim() -eq "443") -and ( $httpsslcertoutput[$i+10].split(":")[1].trim() -ne "AdfsTrustedDevices" ) )
            {
                Write-Warning "ADFS Service binding does not have CTL Store Name set to AdfsTrustedDevices"
                $certbindingissuedetected = $true
            }
        $i = $i + 14
        continue
        }
    $i++
}
If ( $certbindingissuedetected -eq $false ) { Write-Host "Check Passed: No certificate binding issues detected" }
}
function checkadfstrusteddevicesstore()
{
## check for CA issued (non-self signed) certs in the AdfsTrustedDevices cert store
Write-Host; Write-Host "2 – Checking AdfsTrustedDevices cert store for non-self signed certificates"
$certlist = Get-Childitem cert:\LocalMachine\AdfsTrustedDevices -recurse | Where-Object {$_.Issuer -ne $_.Subject}
If ( $certlist.count -gt 0 )
{
    Write-Warning "The following non-self signed certificates are present in the AdfsTrustedDevices store and should be removed"
    $certlist | Format-List Subject
}
Else { Write-Host "Check Passed: No non-self signed certs present in AdfsTrustedDevices cert store" }
}
function checkproxytrustcerts
{
    Param ([bool]$repair=$false)
    Write-Host; Write-Host("3 – Checking AdfsTrustedDevices cert store is in sync with ADFS Proxy Trust config")
    $doc = new-object Xml
    $doc.Load("$env:windir\ADFS\Microsoft.IdentityServer.Servicehost.exe.config")
    $connString = $doc.configuration.'microsoft.identityServer.service'.policystore.connectionString
    $command = "Select ServiceSettingsData from [IdentityServerPolicy].[ServiceSettings]"
    $cli = new-object System.Data.SqlClient.SqlConnection
    $cli.ConnectionString = $connString
    $cmd = new-object System.Data.SqlClient.SqlCommand
    $cmd.CommandText = $command
    $cmd.Connection = $cli
    $cli.Open()
    $configString = $cmd.ExecuteScalar()
    $configXml = new-object XML
    $configXml.LoadXml($configString)
    $rawCerts = $configXml.ServiceSettingsData.SecurityTokenService.ProxyTrustConfiguration._subjectNameIndex.KeyValueOfstringArrayOfX509Certificate29zVOn6VQ.Value.X509Certificate2
    #$ctl = dir cert:\LocalMachine\ADFSTrustedDevices
    $store = new-object System.Security.Cryptography.X509Certificates.X509Store("ADFSTrustedDevices","LocalMachine")
    $store.open("MaxAllowed")
    $atLeastOneMismatch = $false
    $badCerts = @()
    foreach($rawCert in $rawCerts)
    {   
        $rawCertBytes = [System.Convert]::FromBase64String($rawCert.RawData.'#text')
        $cert=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2(,$rawCertBytes)
        $now = Get-Date
        if ( ($cert.NotBefore -lt $now) -and ($cert.NotAfter -gt $now))
        {
            $certThumbprint = $cert.Thumbprint
         $certSubject = $cert.Subject
         $ctlMatch = dir cert:\localmachine\ADFSTrustedDevices\$certThumbprint -ErrorAction SilentlyContinue
         if ($ctlMatch -eq $null)
         {
       $atLeastOneMismatch = $true
          Write-Warning "This cert is NOT in the CTL: $certThumbprint – $certSubject"
       if ($repair -eq $true)
       {
        write-Warning "Attempting to repair"
        $store.Add($cert)
        Write-Warning "Repair successful"
       }
                else
                {
                    Write-Warning ("Please install KB.2964735 or re-run script with -syncproxytrustcerts switch to add missing Proxy Trust certs to AdfsTrustedDevices cert store")
                }
         }
        }
    }
    $store.Close()
    if ($atLeastOneMismatch -eq $false)
    {
     Write-Host("Check Passed: No mismatched certs found. CTL is in sync with DB content")
    }
}
checkhttpsyscertbindings
checkadfstrusteddevicesstore
checkproxytrustcerts($syncproxytrustcerts)
Write-Host; Write-Host("All checks completed.")

问题 1:存在特定于 IP 的绑定

绑定可能与端口 443 上的 AD FS 证书绑定冲突。

IP:port 绑定的优先级最高。 如果 IP:port 绑定位于 AD FS SSL 证书绑定中,http.sys 始终使用该证书进行 SSL 通信。 若要解决此问题,请使用以下方法。

  1. 删除 IP:port 绑定

    请注意,删除 IP:端口绑定后可能会恢复该绑定。 例如,使用此 IP:port 绑定配置的应用程序可能会在下一次服务启动时自动重新创建它。

  2. 使用另一个 IP 地址进行 AD FS SSL 通信

    如果需要 IP:port 绑定,请将 ADFS 服务 FQDN 解析为任何绑定中未使用的另一个 IP 地址。 这样,http.sys 将使用 Hostname:port 绑定进行 SSL 通信。

  3. 将 AdfsTrustedDevices 设置为 IP:port 绑定的 CTL 存储

    如果无法使用上述方法,这是最后的方法。 但在将默认 CTL 存储更改为 AdfsTrustedDevices 之前,最好先了解以下条件:

    • 为何存在 IP:端口绑定。
    • 如果绑定依赖于默认 CTL 存储进行客户端证书身份验证。

问题 2:AD FS 证书绑定未将 CTL 存储名称设置为 AdfsTrustedDevices

如果安装了 Microsoft Entra Connect,请使用 Microsoft Entra Connect 为所有 AD FS 服务器上的 SSL 证书绑定将 CTL 存储名称设置为 AdfsTrustedDevices。 如果未安装 Microsoft Entra Connect,请在所有 AD FS 服务器上运行以下命令,重新生成 AD FS 证书绑定。

Set-AdfsSslCertificate -Thumbprint Thumbprint

问题 3:AdfsTrustedDevices 证书存储中存在非自签名证书

如果 CA 颁发的证书位于通常只有自签名证书的证书存储中,则从存储生成的 CTL 将仅包含 CA 颁发的证书。 AdfsTrustedDevices 证书存储区是应仅具有自签名证书的存储区。 这些证书包括:

  • MS-Organization-Access:用于颁发工作区加入证书的自签名证书。
  • ADFS 代理信任:每个 Web 应用程序代理 服务器的证书。

每个 Web 应用程序代理服务器的证书。

因此,请从 AdfsTrustedDevices 证书存储中删除任何 CA 颁发的证书。

问题 4:安装KB2964735或使用 -syncproxytrustcerts 重新运行脚本

当与 AD FS 服务器建立代理信任关系时,客户端证书将写入 AD FS 配置数据库,并添加到 AD FS 服务器上的 AdfsTrustedDevices 证书存储中。 对于 AD FS 场部署,客户端证书应同步到其他 AD FS 服务器。 如果出于某种原因未进行同步,则代理信任关系将仅适用于建立信任的 AD FS 服务器,而不适用于其他 AD FS 服务器。

若要解决此问题,请使用以下方法之一。

方法 1

在所有 AD FS 服务器上安装 KB 2964735 中所述的更新。 安装更新后,客户端证书的同步应会自动进行。

方法 2

使用 – syncproxytrustcerts 开关运行脚本,以手动将客户端证书从 AD FS 配置数据库同步到 AdfsTrustedDevices 证书存储。 脚本应在场中的所有 AD FS 服务器上运行。

注意

这不是永久的解决方案,因为客户端证书将定期续订。

问题 5:已通过所有检查。 但问题仍然存在

检查是否存在时间或时区不匹配。 如果时间匹配但时区不匹配,代理信任关系也将无法建立。

检查 AD FS 服务器和 WAP 服务器之间是否存在 SSL 终止

如果 AD FS 服务器与 WAP 服务器之间的网络设备上发生 SSL 终止,AD FS 和 WAP 之间的通信将中断,因为通信基于客户端证书。

在 AD FS 和 WAP 服务器之间禁用网络设备上的 SSL 终止。

使用转储令牌应用

调试联合身份验证服务的问题以及验证自定义声明规则时,转储令牌应用非常有用。 它不是官方解决方案,而是一个很好的独立调试解决方案,建议用于故障排除目的。

使用转储令牌应用之前

在使用转储令牌应用之前,需要:

  1. 获取要访问的应用程序的信赖方信息。 如果实现了 OAuth 身份验证,则还获取 OAuth 客户端信息。
  2. 设置转储令牌应用。

获取信赖方和 OAuth 客户端信息

如果使用传统的信赖方,请执行以下步骤:

  1. 在 AD FS 服务器上,使用“以管理员身份运行”选项打开Windows PowerShell。

  2. 运行以下命令,将 AD FS 2.0 组件添加到Windows PowerShell:

    Add-PSSnapin Microsoft.Adfs.PowerShell
    
  3. 通过运行以下命令获取信赖方信息:

    $rp = Get-AdfsRelyingPartyTrust RPName
    
  4. 通过运行以下命令获取 OAuth 客户端信息:

    $client = Get-AdfsClient ClientName
    

如果在 Windows Server 2016 中使用应用程序组功能,请执行以下步骤:

  1. 在 AD FS 服务器上,使用“以管理员身份运行”选项打开Windows PowerShell。

  2. 通过运行以下命令获取信赖方信息:

    $rp = Get-AdfsWebApiApplication ResourceID
    
  3. 如果 OAuth 客户端是公共的,请运行以下命令获取客户端信息:

    $client = Get-AdfsNativeClientApplication ClientName
    

    如果 OAuth 客户端是机密客户端,请运行以下命令获取客户端信息:

    $client = Get-AdfsServerApplication ClientName
    

设置转储令牌应用

若要设置转储令牌应用,请在Windows PowerShell窗口中运行以下命令:

$authzRules = "=>issue(Type = `"http://schemas.microsoft.com/authorization/claims/permit`", Value = `"true`");"
$issuanceRules = "x:[]=>issue(claim=x);"
$redirectUrl = "https://dumptoken.azurewebsites.net/default.aspx"
$samlEndpoint = New-AdfsSamlEndpoint -Binding POST -Protocol SAMLAssertionConsumer -Uri $redirectUrl
Add-ADFSRelyingPartyTrust -Name "urn:dumptoken" -Identifier "urn:dumptoken" -IssuanceAuthorizationRules $authzRules -IssuanceTransformRules $issuanceRules -WSFedEndpoint $redirectUrl -SamlEndpoint $samlEndpoint

现在,请继续使用以下故障排除方法。 在每个方法的末尾,查看问题是否已解决。 如果没有,请使用其他方法。

故障排除方法

检查授权策略,查看用户是否受到影响

在此方法中,首先获取策略详细信息,然后使用转储令牌应用诊断策略,以查看用户是否受到影响。

获取策略详细信息

$rp。IssuanceAuthorizationRules 显示信赖方的授权规则。

在 Windows Server 2016 及更高版本中,可以使用 $rp。 AccessControlPolicyName 用于配置身份验证和授权策略。 如果$rp。 AccessControlPolicyName 具有值,即控制授权策略的访问控制策略已到位。 在这种情况下,$rp。IssuanceAuthorizationRules 为空。 使用 $rp。ResultantPolicy 可查找有关访问控制策略的详细信息。

如果$rp。ResultantPolicy 没有有关策略的详细信息,请查看实际声明规则。 若要获取声明规则,请执行以下步骤:

  1. 运行以下命令,将访问控制策略设置为$null:
    Set-AdfsRelyingPartyTrust -TargetRelyingParty $rp -AccessControlPolicyName $null
  2. 通过运行以下命令获取信赖方信息:
    $rp = Get-AdfsRelyingPartyTrust RPName
  3. 检查 $rp.IssuanceAuthorizationRules$rp. AdditionalAuthenticationRules
使用转储令牌应用诊断授权策略
  1. 将转储令牌身份验证策略设置为与失败的信赖方相同。

  2. 让用户根据设置的身份验证策略打开以下链接之一。

    • WS-Fed: https://FederationInstance/adfs/ls?wa=wsignin1.0&wtrealm=urn:dumptoken
    • SAML-P: https://FederationInstance/adfs/ls/IdpInitiatedSignOn?LoginToRP=urn:dumptoken
    • 强制多重身份验证: https://FederationInstance/adfs/ls?wa=wsignin1.0&wtrealm=urn:dumptoken&wauth=http://schemas.microsoft.com/claims/multipleauthn
  3. 在“Sign-In”页上登录。

你得到的是用户的一组声明。 查看授权策略中是否存在基于这些声明显式拒绝或允许用户的任何内容。

检查是否有任何缺失或意外的声明导致拒绝对资源的访问

  1. 将转储令牌应用中的声明规则配置为与失败信赖方的声明规则相同。

  2. 将转储令牌身份验证策略配置为与失败的信赖方相同。

  3. 让用户根据设置的身份验证策略打开以下链接之一。

    • WS-Fed: https://FederationInstance/adfs/ls?wa=wsignin1.0&wtrealm=urn:dumptoken
    • SAML-P: https://FederationInstance/adfs/ls/IdpInitiatedSignOn?LoginToRP=urn:dumptoken
    • 强制多重身份验证: https://FederationInstance/adfs/ls?wa=wsignin1.0&wtrealm=urn:dumptoken&wauth=http://schemas.microsoft.com/claims/multipleauthn
  4. 在“Sign-In”页上登录。

这是信赖方要为用户获取的声明集。 如果有任何声明缺失或意外,请查看颁发策略以找出原因。

如果存在所有声明,请与应用程序所有者检查,以查看缺少或意外的声明。

检查是否需要设备状态

如果设备声明检查授权规则,请验证从转储令牌应用获取的声明列表中是否缺少这些设备声明中的任何一个。 缺少的声明可能会阻止设备身份验证。 若要从转储令牌应用获取声明,请按照检查授权策略是否受影响的方法中的使用转储令牌应用诊断授权策略部分中的步骤进行操作。

以下是设备声明。 授权规则可能会使用其中一些规则。

  • http://schemas.microsoft.com/2012/01/devicecontext/claims/registrationid
  • http://schemas.microsoft.com/2012/01/devicecontext/claims/displayname
  • http://schemas.microsoft.com/2012/01/devicecontext/claims/identifier
  • http://schemas.microsoft.com/2012/01/devicecontext/claims/ostype
  • http://schemas.microsoft.com/2012/01/devicecontext/claims/osversion
  • http://schemas.microsoft.com/2012/01/devicecontext/claims/ismanaged
  • http://schemas.microsoft.com/2012/01/devicecontext/claims/isregistereduser
  • http://schemas.microsoft.com/2014/02/devicecontext/claims/isknown
  • http://schemas.microsoft.com/2014/02/deviceusagetime
  • http://schemas.microsoft.com/2014/09/devicecontext/claims/iscompliant
  • http://schemas.microsoft.com/2014/09/devicecontext/claims/trusttype

如果缺少声明,请按照 使用已注册的设备配置本地条件访问 中的步骤操作,确保为设备身份验证设置了环境。

如果存在所有声明,请查看转储令牌应用中声明的值是否与授权策略中所需的值匹配。