使用基于声明的身份验证的 SharePoint Online 中的远程身份验证

摘要:  了解如何对使用 SharePoint 客户端对象模型的客户端应用程序中的 Microsoft SharePoint Online 进行身份验证。

上次修改时间: 2015年4月22日

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

本文内容
使用基于声明的身份验证的 SharePoint Online 中的远程身份验证简介
SharePoint 身份验证概述
基于声明的身份验证的发展
SharePoint 声明身份验证序列
对 SharePoint Online 中的远程身份验证使用客户端对象模型
审阅 SharePoint Online 远程身份验证示例代码项目
结论
关于作者
其他资源

供稿人:  Robert Bogue,Thor Projects,LLC (Microsoft SharePoint MVP)

目录

  • 使用基于声明的身份验证的 SharePoint Online 中的远程身份验证简介

  • SharePoint 身份验证概述

  • 基于声明的身份验证的发展

  • SharePoint 声明身份验证序列

  • 对 SharePoint Online 中的远程身份验证使用客户端对象模型

  • 审阅 SharePoint Online 远程身份验证示例代码项目

  • 结论

  • 其他资源

  • 关于作者

单击以获取代码  下载代码:使用客户端对象模型的 SharePoint Online 中的远程身份验证

使用基于声明的身份验证的 SharePoint Online 中的远程身份验证简介

是否依赖基于云的服务(如 Microsoft SharePoint Online)不能轻易决定,还经常因为要考虑内部需要访问组织的数据而不能实施。在本文中,我通过以下方法打消了这一顾虑:提供一个用来构建客户端应用程序的框架和代码,该客户端应用程序通过使用 SharePoint 2010 客户端对象模型根据 SharePoint Online 对用户进行远程身份验证。

备注

虽然这篇文章主要涉及 SharePoint Online,但其中讨论的技术也适用于远程 SharePoint 2010 服务器使用基于声明的身份验证的任何环境。

我将回顾 SharePoint 2010 身份验证方法、提供使用声明模式身份验证的 SharePoint 2010 一些操作的细节、描述如何开发一套工具来使对服务器的远程身份验证与客户端对象模型一起工作。

SharePoint 身份验证概述

在 Office SharePoint Server 2007 中,有两种身份验证类型:一种是 Windows 身份验证,它依赖于通过 HTTP 标头传输的身份验证信息;另一种是基于模板的身份验证,它使用 Microsoft ASP.NET 成员资格和角色引擎管理用户和角色(或组)。与 SharePoint 2003 版本使用的身份验证技术相比,这是一项很大的改进,因为 2003 版本完全依赖于 Windows,导致在很多情况下身份验证仍会失效,如联盟登录和单一登录。

下面以仅使用 Windows 身份验证的环境为例,说明完全依赖 Windows 身份验证的不足之处。在此环境中,如果用户的计算机未加入到域,或其配置未设置为自动传输凭据,则无论用户访问哪个 Web 应用程序,还是从哪个程序中访问,都被提示输入凭据。因此,如果 intranet.contoso.com 上有一个基于 SharePoint 的 Intranet,并且"我的站点"位于 my.contoso.com 上,将提示用户两次输入凭据。如果他们从每个站点打开 Microsoft Word 文档,他们不仅得到两次提示,还会得到两次针对 Microsoft Excel 的提示。显然,这不是最佳用户体验。

但是,如果该网络使用基于窗体的身份验证,则用户登录到 SharePoint 后,在其他应用程序(如 Word 和 Excel)中将不再提示进行身份验证。不过,这两个 Web 应用程序中的每一个都会提示用户进行身份验证。

联盟登录系统(如 Windows Live ID)已存在,但很难将它们集成到 Office SharePoint Server 2007 中。从根本上说,基于窗体的机制旨在对本地用户进行身份验证,即它不支持针对基于联盟系统的身份验证。SharePoint 2010 通过添加对基于声明的身份验证的直接支持解决了这一问题。这使 SharePoint 2010 能够依靠第三方对用户进行身份验证,并提供有关该用户角色的信息。

基于声明的身份验证的发展

由于计算机可以有多个用户,授权一直很棘手。首先,操作系统对用户进行验证。然后,操作系统告诉应用程序是哪个用户。这是第一次声明,由操作系统对应用程序做出。此次声明的核心是用户的身份。操作系统确定用户身份(可能是通过用户提供的密码来进行的),应用程序并不确定用户身份,而是直接信任操作系统。

这种身份验证过程是有效的,但是,如果用户必须在他们未登录到的系统上使用应用程序,情况就不同了。此时,应用程序将不得不执行自己的身份验证。它最初使用的方法与操作系统相同,即要求用户名和密码。这种身份验证过程也是有效的,但它要求每个应用程序都验证一次用户名和密码。维护多个单独的身份验证数据库就成为问题,因为用户想在多个应用程序之间使用相同的用户名和密码。

使用相同的用户名和密码创建帐户并不难管理。然而,随着对安全关注的不断增加,要求用户定期更改其密码,这就导致了一种不易管理的局面,即用户发现很难使自己的密码在不同应用程序之间保持同步。共享的身份验证机制解决了这个问题。重申一遍,应用程序可以依赖第三方对用户进行身份验证。

共享身份验证数据库最常见的一种方法是使用 Kerberos 协议。Kerberos 协议提供了一种机制,使用户能够根据集中的服务器进行身份验证,然后通过由该服务器签署的一张票证传达用户的身份。这种方法的优点是只有集中的服务器必须知道用户的密码或其他身份信息,这样就很好地提供了身份验证信息,但它依赖用户身份的单一存储。

如今,您不能控制应用程序的某些用户使用的身份。例如,某个组织为其他公司提供薪金或退休计划服务。这些组织可能需要接受属于许多其他公司的用户,而不需要逐个对这些用户进行身份验证。他们认为与自己签有合同的组织会识别用户。在这些情况下,不存在用于进行身份验证的集中服务器,也没有可以验证每个用户的集中实体。

同样,如果您有一个旨在与多个伙伴合作的 Extranet 网站,您可能不希望管理所有这些合作伙伴的员工的用户帐户,甚至让合作伙伴自己管理它们。相反,您只想获得用户身份的远程服务器声明。

这是基于声明的登录的强大功能之一。您的系统所信任的另一个系统会提供用户身份的声明。

有很多标准(例如 WS 联合身份验证、WS-安全性和 WS-Trus)定义了这种安排的工作方式。最相关的是 WS 联合身份验证,因为它描述了一种特定的联合身份验证交换方法。与许多其他 Microsoft 和非 Microsoft 产品一样,SharePoint 2010 也实施了 WS 联合身份验证标准。这意味着 SharePoint 声明实施可以与许多其他系统进行交流。

除了前面所述的身份验证信息,还有使基础结构做出其他用户声明的功能,包括配置文件属性,如姓名和电子邮件地址。这项声明还可以包含角色或用户所属的组。这将便于应用程序(包括 SharePoint 2010)使用声明提供程序(称为颁发方)信任的有关用户的内容。然后,应用程序可以将授权设置为对声明令牌中传达的角色执行某些操作。

由于声明不仅仅是传递简单身份信息,因此需要强制执行有关规则,明确应用程序将从第三方接受何种声明类型。如前面所述,WS 信任标准支持一方可以依赖于另一方的思想。此外,它还允许信任链,即应用程序(如 SharePoint 2010)信任一个内部提供程序(如 Active Directory 联合身份验证服务 (AD FS) 2.0),后者进而信任另一方甚至更多其他方。AD FS 2.0 基于从它信任的颁发方收到的信息为 SharePoint 创建它自己的声明令牌。这是非常有用的,因为 AD FS 2.0 是一个声明转换引擎,即它能将一个声明(如属性)转换为另一个声明(如角色成员资格)。AD FS 2.0 也可以筛选第三方做出的声明,使该第三方不能将一个声明传递给用户在其中担任管理员角色的应用程序。

SharePoint 声明身份验证序列

您已经了解有关基于声明的身份验证的优点,现在我们看一看在 SharePoint 中使用基于声明的安全性时实际会发生什么。使用经典身份验证时,您期望 SharePoint 在客户端颁发一个 HTTP 状态代码 401,指示服务器支持的 HTTP 身份验证类型。然而,在声明模式中会发生更复杂的交互。以下是 SharePoint 通过声明同时为 Windows 身份验证和 Windows Live ID 配置时,SharePoint 执行序列的详细叙述。

  1. 用户在受保护的站点上选择一个链接,客户端发送请求。

  2. 服务器响应 HTTP 状态代码 302,表示临时重定向。目标页是 /_layouts/authenticate.aspx,附带查询字符串参数 Source,其中包含用户最初请求的服务器相关的源 URL。

  3. 客户端请求 /_layouts/authenticate.aspx。

  4. 服务器响应一个指向 /_login/default.aspx 的 302 临时重定向和一个查询字符串参数 ReturnUrl,其中包括身份验证页及其查询字符串。

  5. 客户端请求 /_login/default.aspx 页。

  6. 服务器响应一个页面,提示用户选择身份验证方法。这是因为服务器配置为接受来自多个安全令牌服务 (STS) 的声明,其中包括内置的 SharePoint STS 和 Windows Live ID STS。

  7. 用户从下拉列表中选择合适的登录提供程序,客户端在 /_login/default.aspx 上发布响应。

  8. 服务器响应一个指向 /_trust/default.aspx 的 302 临时重定向和一个查询字符串参数 trust,其中包含用户选择的信任提供程序、一个 ReturnUrl 参数(其中包含 authenticate.aspx 页)以及另一个包含源的查询字符串参数。源仍是 ReturnUrl 参数的一部分。

  9. 客户遵循重定向并获取 /_trust/default.aspx。

  10. 服务器响应一个指向标识提供程序的 URL 的 302 临时重定向。对于 Windows Live ID,该 URL 是 https://login.live.com/login.srf 并带有用于标识 Windows Live ID 站点的一系列参数和一个 wctx 参数(与之前提供的 ReturnUrl 查询字符串相匹配)。

  11. 客户端和服务器基于 Windows Live ID 和用户的操作反复交换信息,最后将结果发布到 /_trust/default.aspx,这是在 Windows Live ID 中配置的。该发布内容包括一个安全声明标记语言 (SAML) 令牌,此令牌包含用户的身份标识和指定 ID 正确的 Windows Live ID 签名。

  12. 服务器响应一个指向 /_layouts/authenticate.aspx(最初是作为 ReturnUrl 查询字符串参数中的重定向 URL 提供的)的重定向。此值是作为 wctx 从 声明提供程序 返回的,其形式为一个窗体发布变量。在重定向过程中,/_trust/default.aspx 页写入两个或更多加密和编码的身份验证 Cookie,在每次请求时这些 Cookie 会重新传输到网站。这些 Cookie 包含一个或多个 FedAuth Cookie 和一个 rtFA Cookie。FedAuth Cookie 支持联盟授权,rtFA Cookie 支持用户从所有 SharePoint 网站注销,即使注销过程是从非 SharePoint 站点开始的。

  13. 客户端使用源 URL 的查询字符串参数请求 /_layouts/authenticate.aspx。

  14. 服务器响应一个指向源 URL 的 302 临时重定向。

备注

如果对于用户访问 Web 应用程序所在区域只有一个身份验证机制,将不提示用户选择使用哪个身份验证(见步骤 6)。相反,这种情况下,/_login/default.aspx 立即将用户重定向到合适的身份验证提供程序(本例中为 Windows Live ID)。

请特别注意,在此过程中,FedAuth Cookie 是使用 HTTPOnly 标志写入的,这就使得在客户端应用程序中很难对 SharePoint Online 使用远程身份验证。此标志旨在防止跨站点脚本 (XSS) 攻击。在跨站点脚本攻击中,恶意用户会将脚本注入传输的页面或使用当前页上可用的 Cookie 来实现某些恶意目的。Cookie 上的 HTTPOnly 标志可防止 Internet Explorer 允许从客户端脚本访问 Cookie。Microsoft .NET Framework 也遵守 HTTPOnly 标志,禁止从 .NET Framework 对象模型直接检索 Cookie。

备注

对于 SharePoint Online,FedAuth Cookie 是用 HTTPOnly 标志写入的。但是,对于内部部署的 SharePoint 2010 安装,管理员可以修改 web.config 文件以呈现不带该标记的普通 Cookie。

对 SharePoint Online 中的远程身份验证使用客户端对象模型

对远程身份验证使用 SharePoint 客户端对象模型的第一步是获取一个 ClientContext 对象。正是该客户端上下文对象将对象模型中的其他操作连接到服务器和指定的站点。在基于 Windows 的 HTTP 身份验证方案中,客户端上下文的行为与 Internet Explorer 相同;如果服务器在 Intranet 区域中,它自动将凭据传输到服务器。大多数情况下,这种工作方式很奏效。接着服务器处理凭据,并自动对用户进行身份验证。

在基于表单的身份验证环境中,您也可以使用 FormsAuthenticationLoginInfo 对象将基于表单的身份验证提供给服务器。但是,这只适用于基于表单的身份验证而不适用于基于联盟的声明方案,因为 SharePoint 并不具有实际身份验证过程。

创建一个经过身份验证的 ClientContext 对象需要多个步骤。首先,用户必须能够以交互方式登录到远程系统。第一步,用户通过联合身份验证提供程序登录到 SharePoint,SharePoint 必须发出其身份验证 Cookie。第二步,代码必须检索身份验证 Cookie。第三步,必须将这些 Cookie 添加到 ClientContext 对象。

为远程身份验证启用"用户登录"

.NET Framework 包含一个 System.Windows.Forms.WebBrowser 对象,该对象用于在应用程序内启用 Web 浏览器。若要使用户能够登录到联合身份验证提供程序,就必须创建并显示该对象。但目的是为检索 SharePoint Online 发出的身份验证 Cookie。若要确定登录过程的完成时间,您必须在 Navigated 事件上注册一个处理程序。该事件会在浏览器完成导航之后触发。该事件处理程序监视用户是否返回到其开始导航的 URL。如果返回了,则代码知道用户已完成登录序列。

由于 FedAuth Cookie 是使用 HTTPOnly 标记写入的,因而不能从 .NET Framework 访问。若要检索 Cookie,必须调用 WININET.dll。.NET Framework 可以通过 PInvoke(平台调用)调用基于 COM 的 DLL 方法。在本例中,要调用的方法是 InternetGetCookieEx。这样可以返回常规 Cookie 和带有 HTTPOnly 标记的 Cookie。但是,该方法只有使用 Internet Explorer 8 时才奏效。检索到 Cookie 后,必须将其添加到客户端上下文。

有关 PInvoke 的详细信息,请参阅从托管代码调用本机函数

最后一步是从用户登录检索身份验证 Cookie 并将其附加到客户端上下文。遗憾的是,无法直接将 Cookie 添加到请求。不过,可以在 ClientContext 对象向服务器发出请求前调用 ExecutingWebRequest 事件。通过将事件处理程序添加到该事件,您可以添加一个具有身份验证 Cookie 的新请求标头。完成此步骤后,ClientContext 对象就可以正常使用了,其他代码完全不知道该身份验证是基于联合身份验证的。

审阅 SharePoint Online 远程身份验证示例代码项目

本文附带的代码示例演示了这种将 SharePoint 身份验证 Cookie 添加到 ClientContext 对象的技术。您可以使用它提供的一组类执行联盟用户身份验证。您可以从示例程序开始,观察与使用 HTTP 验证的 Web 服务器相比使用这种代码必须做出怎样的更改。

Sp_Ctx SharePoint 身份验证示例客户端应用程序

Sp_Ctx 项目是使用 SharePoint ClientContext 对象检索上下文指向的 Web 信息的命令行程序。

备注

使用 Sp_Ctx 示例时,您必须将 Web URL 指定为 https 请求。将 Web URL 指定为 http 请求将导致异常。

该项目引用 ClaimsAuth 库,但不完全相同。事实上,您会发现主代码看起来与在标准客户端应用程序中的代码几乎完全相同。

01: static void Main(string[] args)
02: {
03:   if (args.Length < 1) { Console.WriteLine("SP_Ctx <url>"); return; }
04:   string targetSite = args[0];
05:   using (ClientContext ctx = ClaimClientContext.GetAuthenticatedContext(targetSite))
06:   {
07:     if (ctx != null)
08:     {
09:       ctx.Load(ctx.Web); // Query for Web
10:       ctx.ExecuteQuery(); // Execute
11:       Console.WriteLine(ctx.Web.Title);
12:     }
13:   }
14:   Console.ReadLine();
15: }

与标准客户端应用程序中的代码相比,该代码唯一的不同在于第 5 行,即我们调用 ClaimClientContext.GetAuthenticatedContext,而不是创建新的 ClientContext。一个很大的不同在于调用 ClaimClientContext.GetAuthenticatedContext 将显示一个窗体,该窗体允许用户将其凭据提供给远程系统,捕获身份验证请求所需的身份验证 Cookie,并将该标头添加到客户端上下文。

SharePoint Online 身份验证示例中的 ClaimClientContext

检查代码的下一层,注意被调用的 ClaimClientContext 对象。它公开了两个方法(一个用于示例中),即 GetAuthenticatedContext 和 GetAuthenticatedCookie。GetAuthenticatedCookie 由 GetAuthenticatedContext 调用。事实上,GetAuthenticatedContext 调用 GetAuthenticatedCookie 以获取 Cookie 并将其包装在上下文中。

GetAuthenticatedCookie 打开显示网站的对话框,并监视需要完成的身份验证请求以便检索身份验证 Cookie。

SharePoint Online 身份验证示例中的 ClaimsWebAuth

ClaimsWebAuth 类获取身份验证 Cookie。它封装一个窗体和一个 WebBrowser 对象。对象构造过程中执行的第一步是收集登录和结束导航页面。该步骤通过 GetClaimParams 方法完成,该方法与 HTTP OPTIONS 方法一起生成一个 Web 请求。

调用 Show 方法时,将创建 WebBrowser 对象并为 Navigated 事件添加一个事件处理程序。每次完成导航 WebBrowser 对象时,都将调用该事件。事件处理程序会检测 Web 浏览器到达导航端 URL 的时间。事件接收器调用 CookieReader,后者从 WinINET 读取以获得 HTTPOnly FedAuth Cookie。

事件接收器准备就绪后,将 WebBrowser 导航到登录 URL 进行身份验证过程。该过程完成后,将身份验证 Cookie 返回给调用方。

SharePoint Online 身份验证示例中的 CookieReader

示例代码的最后一部分是 CookieReader 类,其中包含对 WinINET.dll 的调用和一个用于获取 Cookie 的帮助程序函数。该帮助程序函数名为 GetFedAuthCookie,以"Name=Value"形式返回一个代表 Cookie 的字符串。GetFedAuthCookie 调用 WinINET.dll 方法 InternetGetCookieEx 来获取该 Cookie。

如果传入的字符串缓冲区大小不够大,InternetGetCookieEx 将返回 false。它还会将大小参数设置为所需的缓冲区大小。因此,如果初始缓冲区太小,GetFedAuthCookie 可能必须调用两次 InternetGetCookieEx 才能获得 Cookie 的值。

结论

本文介绍如何通过使用 SharePoint 2010 客户端对象模型为客户端应用程序中的 Microsoft SharePoint Online 执行基于声明的身份验证。SharePoint Online 为那些需要功能强大的 SharePoint 协作平台的公司提供了一个非常有吸引力的灵活选项,而且没有与内部部署软件相关联的运营成本。利用本文中讨论的技术,开发人员可以使用 SharePoint 客户端对象模型创建能够在 SharePoint Online 中远程进行身份验证的客户端应用程序。

关于作者

八年来 Robert Bogue 一直是 Microsoft MVP 计划的参与者。Robert 的最新书籍是 The SharePoint Shepherd’s Guide for End Users(《面向最终用户的 SharePoint 管理员指南》)。您可以在 http://www.SharePointShepherd.com 中找到有关该书籍的更多信息。Robert 在 http://www.thorprojects.com/blog 上开有博客。您可以通过 Rob.Bogue@thorprojects.com 与 Robert 联系。

其他资源

有关使用基于声明的身份验证的 SharePoint Online 中远程身份验证的详细信息,请参见下列资源: