声明提示 2:了解 SharePoint 2010 中基于声明的身份验证

**摘要:**了解与 SharePoint 2010 中基于声明的身份验证相关的五个提示,包括解析声明名称、配置选择区域、默认解决方案部署和解决错误消息。

上次修改时间: 2011年3月14日

适用范围: Business Connectivity Services | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio

本文内容
本文的范围概述
提示 1:在 SharePoint 2010 中配置只在选择区域上使用的自定义声明提供程序
提示 2:解析声明名称
提示 3:登录和身份验证时三个令人担心的登录提示
提示 4:注意自定义声明提供程序的默认解决方案部署
提示 5:通过基于声明的身份验证解决 TrustedMissingIdentityClaimSource 错误
结论
其他资源

**供稿人:**Steve Peschka,Microsoft Corporation

目录

  • 本文的范围概述

  • 提示 1:在 SharePoint 2010 中配置只在选择区域上使用的自定义声明提供程序

  • 提示 2:解析声明名称

  • 提示 3:登录和身份验证时三个令人担心的登录提示

  • 提示 4:注意自定义声明提供程序的默认解决方案部署

  • 提示 5:通过基于声明的身份验证解决 TrustedMissingIdentityClaimSource 错误

  • 结论

  • 其他资源

本文的范围概述

本文针对与 Microsoft SharePoint 2010 中基于声明的身份验证相关的常见问题提供提示与解答。它还提供了一些提示和指导以帮助解决与使用和配置声明相关的问题,并且提供了指向其他资源的链接以帮助您获取详细信息。

提示 1:在 SharePoint 2010 中配置只在选择区域上使用的自定义声明提供程序

我已经听说多次提出了与声明提供程序相关的使用情况问题:您如何配置自定义声明提供程序,以只用于特定 Web 应用程序或一些 Web 应用程序而不是全部这些应用程序?最初,我期望我们能简单地解决此情况,只需将声明提供程序的功能范围限制到 Web 应用程序而不是服务器场即可。看来这行不通。

自定义声明提供程序的功能范围必须始终限制到服务器场级别。如果您将功能的范围配置为任何不同的级别,则将获得错误"未实现该方法或操作"。

如果功能范围限制到服务器场级别,那么如何将声明提供程序配置为只在所选的 Web 应用程序或区域上使用?答案是复杂的。首先,了解 SPClaimProviderDefinition 类中声明提供程序的两个非常重要的属性至关重要:IsEnabled 属性和 IsUsedByDefault 属性。默认情况下,当您安装一个新声明提供程序功能时,该声明提供程序的 IsEnabled 和 IsUsedByDefault 属性设置为 true。这意味着您的声明提供程序在某区域启用安全声明标记语言 (SAML) 声明的所有位置使用。因此,若要能够将声明提供程序配置为只在所选区域上使用,首先需要将 IsUsedByDefault 属性更改为 false。只要 IsEnabled 等于 true,IsUsedByDefault 等于 false,我们就可以按区域配置对声明提供程序的使用。

很明显下一个问题是,如何将 IsUsedByDefault 属性设置为 false?此处存在两个选项。一个选项使用您为自定义声明提供程序创建的功能接收器并配置属性。在 FeatureActivated 事件的重写(您应该已经编码)中,可以使用 SPClaimProviderManager 来获取对提供程序的引用并将 IsUsedByDefault 属性设置为 false。下面是在我的声明提供程序之一中使用的示例。

SPClaimProviderManager cpm = SPClaimProviderManager.Local;
 
foreach (SPClaimProviderDefinition cp in cpm.ClaimProviders)
{
if (cp.ClaimProviderType == typeof(SqlClaimsProvider.SqlClaims))
       {
       cp.IsUsedByDefault = false;
              cpm.Update();
              break;
       }
}

在此代码中,使用 typeof(SqlClaimsProvider.SqlClaims),将程序集和类名称替换为声明提供程序,例如 typeof(MyProvider.MyClaims)。您还可以将此代码包装在自定义应用程序中。这是我已经完成的,并且将用来在整篇文章中演示其余代码的工作。

图 1 是我的"声明提供程序激活"应用程序的屏幕快照。在该应用程序的左侧是已注册的自定义声明提供程序(在此示例中只有一个)的列表。已注册自定义声明提供程序下方的复选框用来更改所选的已注册自定义声明提供程序的 IsEnabled 和 IsUsedByDefault 属性。

图 1. 显示已注册的自定义声明提供程序的"声明提供程序激活"应用程序

声明提供程序激活应用程序

若要设置属性,首先选择自定义声明提供程序,选择相应框来设置 IsEnabled 和 IsUsedByDefault 属性,然后单击"更新"按钮。

声明提供程序配置为 IsEnabled 而非 IsUsedByDefault 后,可以配置其使用位置。声明提供程序以这种方式进行配置后,仅当区域的 SPIisSettings 在 ClaimsProviders 属性中包含声明提供程序的名称时才使用它。如果您尝试以一般方式这样做,则获得这些信息会稍微有些困难,因为我使用的是"声明提供程序激活"应用程序。第一步是使用 SPService 类来完成枚举所有 Web 应用程序。

//Get the content service.
SPWebService ws = SPWebService.ContentService;
 
//Get each web application.
foreach (SPWebApplication wa in ws.WebApplications)
{
//Enumerate each zone in each web application.
}

枚举 Web 应用程序中的每个区域是不太常见的操作。下面是如何枚举每个区域的示例。

foreach (SPAlternateUrl aam in wa.AlternateUrls)
{
//Look at each zone to see whether it is using SAML claims.
}

若要确定某个区域是否使用 SAML 声明,首先要获取该区域的 SPIisSettings。如前面提到的,为了从 ClaimsProviders 属性添加或删除声明提供程序,我都将需要此信息。以下代码段演示如何获取该区域的 SPIisSetting。

SPIisSettings curConfig = wa.GetIisSettingsWithFallback(aam.UrlZone);

在 curConfig 变量中,我可以查看 ClaimsAuthenticationProviders 属性。如果区域配置为使用声明,则 ClaimsAuthenticationProviders 属性不为 null,并且计数大于零。

我枚举所有声明提供程序,如果发现声明提供程序的某区域的 SPIisSettings 在 ClaimsProviders 属性中包含该声明提供程序的名称,则将该区域添加到区域列表并将其显示为已启用。否则,无法将自定义声明提供程序与该区域结合使用。因此,我仍将该区域添加到区域列表,但将其显示为已禁用。

这是如何生成 Web 应用程序和区域列表以及确定哪些区域可使用自定义声明提供程序的基础。

有了该区域列表,对于任何特定区域,如果声明提供程序名称位于 SPIisSettings 对象的 ClaimsProviders 属性中,则使用该声明提供程序。

ClaimsProviders 属性实际上是一个 string 类型的 IEnumerable,因此该属性有点难以处理,因为它不包含 Add 或 Remove 或 RemoveAt 项目的重载方法。为了克服该问题,我将该属性转换为 List<string>,这样我就可以添加和删除声明提供程序名称,然后将 List<string> 重新分配给 ClaimsProviders 属性。

下面是代码示例。

List<string> providers = theZoneIisSettings.ClaimsProviders.ToList();
 
//NOTE: myClaimProvider is type SPClaimProviderDefinition.
if (EnableProvider)
providers.Add(myClaimProvider.ClaimProvider.Name);
else
       providers.Remove(myClaimProvider.ClaimProvider.Name);
 
//Plug the new values back into the ClaimsProviders Ienumerable.
theZoneIisSettings.ClaimsProviders = providers;
 
//You must get the web application that contains the zone, and then call its
//Update method to save your changes.
theWebApp.Update();

图 2 显示 Web 应用程序和区域选择在"声明提供程序激活"应用程序中的外观。

图 2. 显示特定自定义声明提供程序的 Web 应用程序和区域的"声明提供程序激活"

声明提供程序激活应用程序和区域

在此示例中,菜单显示"启用 Basketball Teams",因为未为该区域启用 Basketball Teams 提供程序。如果该提供程序已启用,则菜单会显示 Disable Basketball Teams。请注意,在该区域上方的区域中,"SharePoint – Anon 配置文件测试"Web 应用程序已禁用。这是因为这些区域未配置为使用 SAML 声明。

这就是全部工作方式。有些复杂,但也有很多配置上的灵活性。

提示 2:解析声明名称

现在,我已经多次见到有关解析声明名称的问题,因此我想要尝试共享有关此问题的信息,说不定您正试图进行疑难解答。我已经见到过名称解析无法完成的情况。例如,当您在键入控件中键入名称然后单击解析按钮时。如果您已开发一个自定义声明提供程序,甚至可以附加调试器,您可能会看到声明提供程序正常工作,但已键入的名称下方仍有一条红色曲线,并且搜索显示未找到任何匹配项。

关于这个特定问题,您将发现默认声明提供程序不再工作。例如,您可以键入"NT 权限/所有验证用户",但无法解析它。

调用某个声明提供程序的 FillResolve 重载时,该声明提供程序引发异常。如您可能已从该提示简介中猜到的,这里特别麻烦的事情是,一个错误的声明提供程序即意味着会使服务器场中的所有名称解析失败。

因此,如果您发现无法使默认声明提供程序解析名称的情况出现,请开始查找自定义声明提供程序。如果您未编写所有这些自定义声明提供程序,则可能需要逐个删除它们才能找到有问题的声明提供程序。另外要关注删除它们的过程,主要是因为如果您按不同的顺序重新添加它们,将不会生成与以前相同的基础声明(因为部分声明基于添加声明提供程序的顺序)。

而此处主要的主题是,遇到此名称解析问题时要查找的内容以及如何解决此问题。

备注

其一,之前信息希望演示自定义声明提供程序开发人员不应在声明提供程序中引发异常。如果引发了异常,则会带来"错误"提供程序阻止在服务器场中进行名称解析的风险。

提示 3:登录和身份验证时三个令人担心的登录提示

身份验证时的三个登录提示问题全部都太常见了。这周末我就遇到了此问题,但是发生在 Active Directory 联合身份验证服务 (ADFS) 服务器上,很不幸我进行了重新生成。这些提示的最常见原因是使用某个错误配置的 Kerberos 协议设置,或使用 Web 应用程序的服务器名称之外的某个名称(禁用的环回方案)。

但是此问题是不同的,特定于 ADFS 服务器,因此我希望捕获它以供将来参考。

Active Directory 联合身份验证服务 (AD FS) 2.0 实际上能够正常将问题写入事件日志中。当打开事件查看器时,您会看到 AD FS 2.0 对应一个单独的节点。AD FS 2.0 节点是查找问题所在的位置。在此特定情况下,我确实在该节点找到了罪魁祸首,只是花费了相当长的时间,因为存在几个不同的原因可能会导致生成这三个令人担心的登录提示。

配置 ADFS 服务器时,执行了以下操作:

  • 将 ADFS 服务器配置为以域帐户运行

  • 使用刚为 ADFS 创建的用于令牌签名的证书

问题是用于 ADFS 的服务帐户没有对令牌签名证书的私钥的权限。这导致了三个登录提示,让人一下子感到有趣、吃惊和沮丧。

若要向服务帐户授予对证书私钥的权限,您需要:

  1. 运行 Microsoft 管理控制台 (MMC)。

  2. 为"本地计算机"添加证书 MMC 管理单元 (该链接可能指向英文页面)(Certmgr.dll)。

  3. 打开"个人"节点。

  4. 右键单击令牌签名证书,然后选择"管理私钥"。

我希望这能节省一些人的时间。

提示 4:注意自定义声明提供程序的默认解决方案部署

我的一位好朋友 Tom W.(创作了 SharePoint 2010 Kerberos 白皮书(该链接可能指向英文页面))提出了一个好观点,是关于解决方案部署限制及对自定义声明提供程序的影响的。请切记,当您开发一个自定义声明提供程序时,它除了在最终用户 Web 应用程序中使用外,还可以在若干个不同的位置使用。例如,当您在管理中心创建 Web 应用程序策略时,它即在该位置使用。当您在"我的网站"上配置用户权限时,即在该位置调用它。如果使用Secure Store Service,也会在该位置调用它。

当构建更大的服务器场时,此问题就会显现。因为这些服务会调入自定义声明提供程序框架,所以需要将每个自定义声明提供程序的程序集放在每台服务器上的全局程序集缓存中。但默认情况下,SharePoint 解决方案部署框架只将解决方案部署到 Web 前端服务器。

当查看解决方案部署的架构时,DeploymentServerType 属性的选项只能是 ApplicationServer 值或 WebFrontEnd 值。而您实际需要这二者。这是因为在较大的服务器场中,您可能不会在应用程序服务器上运行 Web 应用程序服务。如果是这样,这些服务器上的全局程序集缓存中会缺失您的自定义声明提供程序。如果尝试使用任何调用自定义声明提供程序框架的功能,则会因程序集缺失而生成错误。

很遗憾,下面是目前唯一的解决方法:

  1. 在场中的所有服务器上运行 Web 应用程序服务。

  2. 编写自定义部署作业、事件接收器、计时器作业或类似的项目,以获取部署到所有应用程序服务器的程序集。

  3. 手动部署程序集。

所有这些选项都不怎么吸引人。如果必须选取一个,我将挑选第一个选项(在场中的所有服务器上运行 Web 应用程序服务),只需保持这些服务器远离最终用户负载平衡池即可。

现在,我只想引发该问题,以便您能够注意到它,并可以根据需要针对服务器场进行相应规划。再次感谢 Tom 指出该问题。

提示 5:通过基于声明的身份验证解决 TrustedMissingIdentityClaimSource 错误

我曾多次目睹我自己还有他人遇到"TrustedMissingIdentityClaimSource"错误,因此我希望把可能的错误原因都列举出来。情形如下:您在 SharePoint 2010 中设置基于声明的身份验证,并且相当确定一切都配置正确。

但是,当您实际尝试导航到网站时,可能会获得标准 Microsoft ASP.NET 错误页,指示"TrustedMissingIdentityClaimSource"错误(假定您已关闭自定义错误)。当电子邮件地址配置为标识声明但您尝试用来登录的人员在 Active Directory(或您正在使用的任何目录)中没有电子邮件地址时,我最常见到此错误。这会产生混乱,因为您看到自己重定向到了 ADFS(出于此讨论目的,也可以是任何标识提供程序安全令牌服务)。您看到自己已在该位置经过身份验证,但随后在 Microsoft SharePoint Server 上收到"TrustedMissingIdentityClaimSource"错误。

该错误起到一种提醒作用,提醒我的身份(您用来登录的标识)与我的情况(例如,电子邮件地址和其他可用于在 SharePoint 2010 中进行权限设置的声明等属性)之间的差别。

因此,如果您收到该错误,首先应记得检查您用来登录的用户帐户是否具有标识提供程序预期的标识声明值。另外记得如果该属性中没有任何值,则通常情况下,该声明甚至不会发送给 SharePoint Server(例如,它将不会作为空字符串值进行发送)。

结论

本文针对有关 SharePoint 2010 中基于声明的身份验证的一些常见问题提供了解答。它还提供了五个提示和指导以帮助解决与使用和配置声明相关的问题,并且提供了指向其他资源的链接以帮助您获取详细信息。

其他资源

有关详细信息,请参阅以下资源: