SharePoint默认创建的WebApplication是基于windows的身份验证模式,以弹出窗口方式进行身份输入登录。这种方式可能对于国内的企业用户来说感觉不是很友好。一般而言,我们会把这种登录模式变更为FBA(Forms Based Authentication)方式或混合模式,此文章就是告诉大家如何在WebApplication的FBA方式下自定义登录页面。
本文章中不去涉及FBA的配置过程,这部分的内容我会在另一篇文章中单独摘写。
我们假设已经将一个WebApplication配置好FBA。给大家给截图说明下配置后的环境
在配置FBA过程中会修改管理中心、STS、Web应用程序的WebConfig。所以,不管你用何种配置过程和配置工具,都建议开发者先提前备份好这些WebConfig文件。这部分最重要的就是定义MemberShip提供程序和Role提供程序。Provider提供程序由微软方已经提供了很多种,基于LDAP、SunJava、SQL、Open LDAP、SQL Connection String、eDirectory等。当然,我们还可以自己编写特定的Provider哦。这部分我就不在此详解了。
接下来,就是修改Web应用程序的身份验证配置。
这里就涉及到非常重要的两个部分:一是FBA的成员服务程序和角色服务程序;二是指定我们自己的登录页的URL地址。我们的重点是如何自定这个登录页面让他个性化十足。
自定义登录页的地址由开发者根据自己的页面部署情况而定,不要照搬我的配置哦。
启动了FBA的Web应用程序在IIS中的对应网站目录中会多出一个“_forms”目录,这个目录下有一个default.aspx页面,它是默认的登录页面。不幸的是这个页面会继承一个master page母版页,此页当然就是一个内容页了。要想修改这个内容页很不容易,所以我们需要想办法来自定义一个登录页,看下面过程将帮助您完成你所要的一切。
在这给大家一个建议:不要禁用Windows验证,因为它会影响搜索引擎对此Web应用程序站点的搜索。也就是说配置为混合登录模式是最佳企业应用场景。
我们利用VS2012以上版本的开发工具去创建一个SharePoint工程。
第一步:添加引用
Microsoft.IdentityModel
System.IdentityModel
Microsoft.SharePoint
Microsoft.SharePoint.Client.ServerRuntime
Microsoft.SharePoint.IdentityModel
Microsoft.SharePoint.Portal
第二步:添加Layouts目录的映射
这步看截图就行,很简单
第三步:在Layouts目录下新建项
我建议在Layouts目录下再创建一个目录,目录名称自己随便起。在这个自己创建的目录下创建项。
选择创建一个“应用程序页”,给个清晰的文件名称比如”LoginPage.aspx”
第四步:修改这个页面的前端和后台代码
我贴下我的代码,让大家参考
前端页面代码如下
<%@ Assembly Name="DemoProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7a90d4da5639113b" %> <%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %> <%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register TagPrefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Assembly Name="Microsoft.Web.CommandUI, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="LoginPage.aspx.cs" Inherits="DemoProject.Layouts.DemoProject.LoginPage" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title></title> <link rel="stylesheet" type="text/css" href="/_layouts/styles/reset.css" /> <link rel="stylesheet" type="text/css" href="/_layouts/styles/function.css" /> <style> body { background-color: #EDFAFB; margin: 0px; padding: 0px; border: 0px; } /* 两列左侧自适应布局 */ .g-bd2 { margin: 0px; } .g-sd2 { position: relative; float: right; width: 400px; margin-left: -400px; } .g-sd2 > div { position: fixed; height: 100%; background-color: #EDFAFB !important; width:400px; padding-left:20px; padding-top:100px; } .g-sd2 tr { line-height:60px; height:60px; } .g-mn2 { float: left; width: 100%; } .g-mn2c { margin-right: 400px; } .g-mn2c > div { position: fixed; height: 100%; width: 100%; background-image: url(/_layouts/images/logon.png); background-position: right bottom; background-repeat: no-repeat; background-size: contain; background-size:100%; } </style> </head> <body> <div class="g-bd2 f-cb"> <div class="g-mn2"> <div class="g-mn2c"> <div></div> </div> </div> <div class="g-sd2"> <div> <form id="form1" runat="server" class="loginForm"> <asp:Login ID="signInControl" Style="width: 390px" FailureText="用户名或密码错误" MembershipProvider="LdapMember" runat="server" DisplayRememberMe="true" TextBoxStyle-Width="200px" RememberMeSet="true" UserNameLabelText="用户名: " TextLayout="TextOnLeft" PasswordLabelText="密码: " LabelStyle-Font-Bold="false" LabelStyle-Font-Size="Large" LabelStyle-ForeColor="" LabelStyle-Font-Names="宋体" CheckBoxStyle-Font-Bold="false" CheckBoxStyle-Font-Names="宋体" CheckBoxStyle-ForeColor="" CheckBoxStyle-Font-Size="Large" FailureTextStyle-Wrap="true" FailureTextStyle-Font-Names="宋体" FailureTextStyle-Font-Size="Small" LoginButtonStyle-Font-Names="宋体" LoginButtonStyle-Font-Size="Large" LoginButtonImageUrl="/_layouts/images/loginbtn.png" LoginButtonType="Button" TitleText="公共服务平台" TitleTextStyle-ForeColor="#0071C5" TitleTextStyle-Font-Bold="true" TitleTextStyle-Wrap="true" TitleTextStyle-Font-Names="宋体" TitleTextStyle-Font-Size="34px" TitleTextStyle-Height="40px" LoginButtonStyle-BackColor="#0071C5" LoginButtonStyle-Height="35px" LoginButtonStyle-Width="80px" LoginButtonStyle-ForeColor="White" TextBoxStyle-Height="25px" /> <asp:LinkButton ID="lbInternalUsers" runat="server" Text="Active Directory Login" OnClick="lbInternalUsers_OnClick" ForeColor="#0071C5" Font-Size="16px" /> <SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" ID="ClaimsFormsPageMessage" Visible="false" /> <SharePoint:EncodedLiteral ID="ClaimsFormsPageTitle" runat="server" Text="<%$Resources:wss,login_pagetitle%>" EncodeMethod='HtmlEncode' Visible="false" /> <SharePoint:EncodedLiteral ID="ClaimsFormsPageTitleInTitleArea" runat="server" Text="<%$Resources:wss,login_pagetitle%>" EncodeMethod='HtmlEncode' Visible="false" /> </form> <div style="position:fixed;bottom:0px;padding-bottom:20px;"> All rights 2014-2015 ISHTC </div> </div> </div> </div> </body> </html>
上面的代码还请大家仔细看,工程师看懂他们非常容易。
特别注意的地方:login控件的ID属性值必须是“signInControl”,其他的由自己来发挥吧。这个缘由还是因为SharePoint在特定寻找这个控件造成的。
后台代码如下:
using System; using Microsoft.SharePoint; using Microsoft.SharePoint.WebControls; using Microsoft.SharePoint.IdentityModel.Pages; using Microsoft.SharePoint.Mobile.Controls; using Microsoft.SharePoint.Administration; using System.Web; using Microsoft.SharePoint.Utilities; namespace ShengHuaProject.Layouts.ShengHuaProject { public partial class LoginPage : FormsSignInPage { protected void Page_Load(object sender, EventArgs e) { } protected override void OnInit(EventArgs e) { base.OnInit(e); } protected override void OnLoad(EventArgs e) { try { base.OnLoad(e); this.signInControl.LoggingIn += signInControl_LoggingIn; } catch { } } protected void signInControl_LoggingIn(object sender, System.Web.UI.WebControls.LoginCancelEventArgs e) { } protected void lbInternalUsers_OnClick(object sender, EventArgs e) { try { if (null != SPContext.Current && null != SPContext.Current.Site) { SPIisSettings iisSettings = SPContext.Current.Site.WebApplication.IisSettings[SPUrlZone.Default]; if (null != iisSettings && iisSettings.UseWindowsClaimsAuthenticationProvider) { SPAuthenticationProvider provider = iisSettings.WindowsClaimsAuthenticationProvider; Redirect(provider); } } } catch (Exception ex) { } } private void Redirect(SPAuthenticationProvider provider) { string comp = HttpContext.Current.Request.Url.GetComponents(UriComponents.Query, UriFormat.SafeUnescaped); string url = provider.AuthenticationRedirectionUrl.ToString(); if (provider is SPWindowsAuthenticationProvider) { comp = EnsureUrl(comp, true); } SPUtility.Redirect(url, SPRedirectFlags.Default, this.Context, comp); } //http://skyrim:6050/_windows/default.aspx?ReturnUrl= private string EnsureUrl(string url, bool urlIsQueryStringOnly) { if (!url.Contains("ReturnUrl=")) { if (urlIsQueryStringOnly) { url = url + (string.IsNullOrEmpty(url) ? "" : "&"); } else { url = url + ((url.IndexOf('?') == -1) ? "?" : "&"); } url = url + "ReturnUrl="; } return url; } } }
第五步:发布项目到SharePoint站点
发布成功后,到IIS管理器界面上去检查一下你的Web应用程序站点的_layouts目录里是否多了一个“DemoProject”目录,并且在这个目录里有一个“LoginPage.aspx”文件
第六步:登录网站,测试
测试的时候记得先用Windows身份方式以站点管理员的身份登录,设置一个LDAP帐号为网站集管理员。以后的事嘛,就是用表单方式登录开始你的一系列应用了。