绕过 SharePoint2010 中的多重选择验证提供程序页
原文发布于 2011 年 5 月 1 日(星期日)
旁注: 这对管理此网站的大量用户来说又是一大利好消息。此最新版本中现在保留的来自 Word 和 Visual Studio 的格式设置比以前更少了!我不认为这会让此网站变得更糟,而您粉碎了我在这方面的预期,说的难听一点是让我的预期泡汤了。值得庆贺!我正盼着自己也能赶快照着做,弃用 Word、Excel 和 PowerPoint 而选择记事本 - 谁还需要格式设置呢?
我最近需要绕过提供程序选择页,在 SharePoint 2010 的单个区域中启用多个验证提供程序时,会出现该页面。我遇到的虽然是一个相当简单的应用场景,但相应的方法可以举一反三,以支持更复杂的应用场景。就我而言,我在一个区域上启用了 Windows 身份验证和基于表单的身份验证 (FBA)。但我一直希望让用户对此特定应用场景改用 FBA。
完成此项任务相对较简单,只需执行以下步骤即可:
- 在 C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\IDENTITYMODEL\LOGIN 文件夹中创建 default.aspx文件的备份副本。
- 打开 Visual Studio,新建一个 Windows 类库项目。
- 添加对 System.Web、Microsoft.SharePoint.dll 和 Microsoft.SharePoint.IdentityModel.dll 的引用。遗憾的是,只能在 GAC 中找到标识模型程序集,所以我必须获取它的副本,并将它放在我的驱动器的根目录下以便添加引用。有关如何找到和复制它的建议,您可以查看我的文章,里边有具体说明:https://blogs.msdn.com/b/sharepoint_chs/archive/2010/11/25/sharepoint-2010-1.aspx。
- 赋予程序集一个强名称,因为它将进入 GAC。
- 在您的项目中添加一个新的 ASPX 页。老实说,我觉得最简单的办法就是从现有 ASP.NET Web 应用程序项目复制一个页面,这样一下便能将 .aspx、.aspx.cs 和 .aspx. designer. cs 文件全都复制了。此时要记住,我们需要一个名为“default.aspx”的文件,如果该文件中还没有写入代码,页中的标记也最少,那事情会更好办。
- 在代码隐藏文件(.aspx.cs 文件)中,更改命名空间,使其与您当前项目的命名空间一致。
- 更改类,使其从 Microsoft.SharePoint.IdentityModel.Pages.MultiLogonPage 继承。
- 重写 OnLoad 事件。当用户在有多个验证提供程序启用的情况下点击网站时会发生什么情况呢?他们会首先被发送到 /_login/default.aspx 页(我在上面 #1 中描述过的一个页面)。在该页上,用户将选择使用哪种身份验证提供程序,然后他或她便被重定向到正确的页面以进行验证。在这种应用场景中,我说过,我一直希望用户使用 FBA 来进行身份验证,所以我一直想将他们发送到 /_forms/default.aspx。如果您通过正常步骤登录,则会看到,您将被重定向到 /_login/default.aspx,您做出选择后,又回发到 /_login/default.aspx,然后您被重定向到正确的登录页面。所以在此案例中,我只是想看看我的登录页面有无回发。如果没有,则我知道还没有对验证提供程序做出选择。所以我只列举了所有查询字符串值,然后将它们附加到 /_forms/default.aspx,并将用户重定向到那里。整个代码段如下所示:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
try
{
//if this isn't a postback, then the user hasn't selected which
//auth provider they want to use
//in this case we want to always refer the person to forms login
if (!this.IsPostBack)
{
//grab all the query string parameters
System.Text.StringBuilder qp = new System.Text.StringBuilder(2048);
foreach (string key in this.Request.QueryString.Keys)
{
qp.Append(key + "=" + this.Request.QueryString[key] + "&");
}
//redirect to the forms login page
this.Response.Redirect("/_forms/default.aspx?" + qp.ToString());
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
- 现在,编译应用程序,这样您可以得到它的强名称并将其添加到 default.aspx 的标记中。
- 将以下片段粘贴到 default.aspx 中。您只需更改页所继承的类(以下突出显示部分)。请注意,我所做的只是从 /_login/default.aspx 复制它,并用我的自定义类信息替换 Inherits 值:
<%@ Page Language="C#" CodeBehind="Default.aspx.cs" Inherits="MultiAuthLoginPage._Default,MultiAuthLoginPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=907bf41ebba93579" MasterPageFile="~/_layouts/simple.master" %>
<%@ Assembly Name="Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharepointIdentity" Namespace="Microsoft.SharePoint.IdentityModel" Assembly="Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Import Namespace="Microsoft.SharePoint.WebControls" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ID="Content1" ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">
<SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" Id="ClaimsLogonPageTitle" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">
<SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" Id="ClaimsLogonPageTitleInTitleArea" />
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderId="PlaceHolderSiteName" runat="server"/>
<asp:Content ID="Content4" ContentPlaceHolderId="PlaceHolderMain" runat="server">
<SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" Id="ClaimsLogonPageMessage" />
<br />
<br />
<SharepointIdentity:LogonSelector ID="ClaimsLogonSelector" runat="server" />
</asp:Content>
- 在 GAC 中注册您的程序集。
- 将您的新自定义 default.aspx 页复制到 C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\IDENTITYMODEL\LOGIN 文件夹。再次提醒,复制前一定要先备份原始文件!
- 在您的服务器场的每个 Web 前端上执行步骤 1、11 和 12。
一切就这么简单。我用标准用户登录测试了一下,并直接从 Microsoft Office 2010 客户端打开文档。此处还有一件事值得注意:这改变了您的服务器场中所有 Web 应用程序 的行为!那也是它为何是一个简单示例的原因。但是,您可以轻松看到请求的主机名(映射到您的 Web 应用程序),根据正被访问的 Web 应用程序甚至网站集来做出不同的身份验证决定。很明显,您也可以根据所掌握的当前用户的信息做出其他决定。HttpRequest.Context.Current、Page.Request 和 Page.Response 类可以提供大量信息来帮助您做出这些决定。
这是一篇本地化的博客文章。请访问 Bypassing the Multi Authentication Provider Selection Page in SharePoint 2010 以查看原文