在 SharePoint 2010 的自定义声明提供程序中使用 Secure Store Service
最近,在我处理的自定义声明提供程序中使用 Secure Store Service (SSS) 时,发现了一个不同寻常的创新方法。这实际上是一个很有趣的方案,因为我所做的正是很多人想做的 - 自定义声明扩充。我需要连接到远程数据源,以便可以查询有关每个用户的一些其他信息,然后使用这些信息确定哪些声明需要扩充、哪些不需要扩充。
作为在自定义声明提供程序中使用数据源的一般指导原则,必须记住,在执行 SharePoint STS 进程后,自定义声明提供程序程序集在内存中会保持活动状态。这样,通过将“信息”(无论是数据集还是一组凭据等)存储在类级别的变量中以便在下次 IISRESET 之前可用,可以更轻松地检索信息。这样做有很大的限制 — 在实例化您的自定义声明提供程序类时,并非所有 SharePoint 场资源均可用,这正是今天所讲述内容的意义。
在该特定示例中,我希望通过自定义声明提供程序的构造函数从 SSS 中检索数据,然后我打算使用它执行“一些其他操作”;对于我来说,我要在单向信任域中创建 WindowsIdentity,以便我可以使用它创建有权查询远程 Active Directory 的模拟上下文。这时问题出现了:当我尝试在构造函数中通过引用 SSS 来执行任何操作时,总是超时。无论对 SSS 调用什么方法,60 秒后总是失败,并且显示超时错误。
解决方法是直接将代码移出构造函数。在 FillClaimsForEntity 方法重写中调用时,完全相同的代码却可以正常运行。能够在反复试验和出错后找到问题解决办法实属幸运,因此这似乎是一个值得与大家分享的技巧。
只要我们顺着这一特定问题的这一思路(登录到远程域并模拟)走下去,可能会揭示我得出的这种模式之外的其他模式,以及其他难点。
如上所述,因为您的程序集在 STS 进程中保持加载状态,所以您可以使类级别变量“保持活动状态”。因为我当然不希望在需要查询远程域时反复登录,所以我为 WindowsIdentity 创建了一个类级别的变量。模式如下所示:
- 确定我是否已检索 SSS 凭据
- 如果没有,执行代码以完成以下操作:
- 从 SSS 检索凭据
- 使用从 SSS 获取的凭据通过 LogonUser API 登录到远程域
- 实例化 WindowsIdentity 变量,以便它具有远程用户的凭据
- 如果没有,执行代码以完成以下操作:
- 检查 WindowsIdentity 变量是否为 Null
- 如果不是,执行代码以完成以下操作:
- 从 WindowsIdentity.Impersonate() 创建 WindowsImpersonationContext 的新实例
- 查询远程域
- 对 WindowsImpersonationContext 调用 Undo
- 如果不是,执行代码以完成以下操作:
该模式看起来很有效,也是到目前为止我苦思冥想找到的最有效模式。下面就是难点 - 您不希望对 WindowsIdentity 实例调用 Impersonate(),接下来也不对之后生成的 WindowsImpersonationContext 调用 Undo。如果您不撤消模拟,那么根据我的经验,网站将不再呈现。添加 Undo 调用后,一切又开始恢复正常了。
这是一篇本地化的博客文章。请访问 Using Secure Store Service in a Custom Claims Provider with SharePoint 2010 以查看原文