Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
最近,在我处理的自定义声明提供程序中使用 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 以查看原文