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应用程序的身份验证配置。

    wKioL1TQ3KfDo3aiAAHvvcwr5gQ932.jpgwKioL1TQ4AXy4MeAAALU94Mu5Ok693.jpg

    这里就涉及到非常重要的两个部分:一是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目录的映射

    这步看截图就行,很简单

    wKiom1TQ4nvzEttNAALagqqvCxA271.jpg    第三步:在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-p_w_picpath: url(/_layouts/p_w_picpaths/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/p_w_picpaths/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帐号为网站集管理员。以后的事嘛,就是用表单方式登录开始你的一系列应用了。