SharePoint 2010中默认的FBA登录页面非常简单,只提供了一个Asp.Net的Login控件,让用户输入用户名和密码。在大多数情况下,我们需要定制这个页面以满足一些安全需求,比如为登录页面加上验证码等等。

由于SharePoint 2010里的FBA已经变成了基于Claims认证的方式,因此在实现自定义的登录页面时就与MOSS 2007里的做法完全不同了。最显著的一点就是,像Steve Peschka说的,以前的FormsAuthentication类不会再被用到了。现在我们需要用SharePoint的STS来做认证和处理Claims。好在SharePoint提供了相应的借口,让这一切变得容易了许多。这这篇文章里,我将演示如何创建自定义登录页面,并保持默认的master page和样式。

由于要修改默认页面,我不知道这样的做法是否受Microsoft官方支持,如果你要用在你的项目中,风险自负。

创建自定义登录页面

如果我们留意一下会发现,默认的FBA登录页面是_forms/default.aspx。这样的设计有一个好处,就是如果我们修改了default.aspx,它不会影响别的Web app。下面我就在一个default.aspx页面上加了一个验证码功能。

<asp:login id="loginControl"      
    FailureText="<%$Resources:wss,login_pageFailureText%>"      
    runat="server" width="100%" OnLoggingIn="signInControl_LoggingIn"      
    OnAuthenticate="signInControl_Authenticate"> <layouttemplate>      
        <asp:label id="FailureText" class="ms-error" runat="server"/>      
        <table width="100%">      
        <tr>      
            <td nowrap="nowrap">      
                <SharePoint:EncodedLiteral runat="server"      
                    text="<%$Resources:wss,login_pageUserName%>"      
                    EncodeMethod='HtmlEncode'/>      
            </td>      
            <td width="100%">      
                <asp:textbox id="UserName"      
                    autocomplete="off"      
                    runat="server"      
                    class="ms-inputuserfield" width="99%" />      
            </td>      
        </tr>      
        <tr>      
            <td nowrap="nowrap">      
                <SharePoint:EncodedLiteral runat="server"      
                    text="<%$Resources:wss,login_pagePassword%>"      
                    EncodeMethod='HtmlEncode'/>      
            </td>      
            <td width="100%">      
                <asp:textbox id="password" TextMode="Password"      
                    autocomplete="off" runat="server"      
                    class="ms-inputuserfield" width="99%"/>      
            </td>      
        </tr>      
        <tr>        
            <td nowrap="nowrap">        
                <SharePoint:EncodedLiteral runat="server"        
                    text="Secure Code:" EncodeMethod='HtmlEncode'/>        
            </td>        
            <td width="100%">        
                <asp:textbox id="secureCode" autocomplete="off"        
                    runat="server" class="ms-inputuserfield" Width="85%" />        
                <SharePoint:EncodedLiteral ID="secureCodeLit"        
                    runat="server" Text="1234" EncodeMethod="HtmlEncode" />        
            </td>        
        </tr>
        <tr>      
            <td colspan="2" align="right">      
                <asp:button id="login" commandname="Login"      
                    text="<%$Resources:wss,login_pagetitle%>" runat="server" />      
            </td>      
        </tr>      
        <tr>      
            <td colspan="2">      
                <asp:checkbox id="RememberMe"      
                    text="<%$SPHtmlEncodedResources:wss,login_pageRememberMe%>"      
                    runat="server" />      
            </td>      
        </tr>      
        </table>      
    </layouttemplate>      
</asp:login>

我的想法是,当用户登录的时候,只有输入了正确的用户名密码和验证码,这里是1234,之后才能成功登录。页面运行的效果如下:

当然,此时验证码还没有作用,我们必须写一些代码来实现验证的功能。

创建Code Behind类实现验证和登录功能

接下来是为default.aspx实现一个类来实现验证和登录功能。在项目中添加一个类,可以命名为FormsSignInPage。接着是添加一些引用,首先是Microsoft.SharePoint.dll。由于我们要处理Claims,System.IdentityModel.dll和Microsoft.IdentityModel.dll也是必须的。另外,SharePoint有一个自己的处理Claims的Module,Microsoft.SharePoint.IdentityModel.dll。添加对它的引用时,需要定位到它所在的目录。引用添加完,看起来像下面这样。

我们的类,FormsSignInPage,当然可以从Asp.Net的Page类派生,但是如果我们看一下默认的登录页面,它是派生自IdentityModelSignInPageBase。这个类在Microsoft.SharePoint.IdentityModel.Pages名字空间下,它提供了一些属性和方法,在处理登录时很方便。所以,我决定我的FormsSignInPage也从这个类派生。

当用户点击页面上的登录按钮时,有两个Login控件的事件需要处理,一个是LoggingIn,在这个事件中,我们可以处理验证码。另一个是Authenticate,在这个事件中可以实现真正的登录。

protected void signInControl_LoggingIn(objectsender, LoginCancelEventArgs e)     
{     
    LoginControl login = sender asLoginControl;     
    login.UserName = login.UserName.Trim();     
    if(string.IsNullOrEmpty(login.UserName))     
    {     
        ClaimsFormsPageMessage.Text = "The server could not sign you in. The user name cannot be empty.";     
        e.Cancel = true;     
    }     
    if(string.IsNullOrEmpty(secureCode.Text) ||     
        !string.Equals(secureCode.Text.ToLower(), secureCodeLit.Text.ToLower()))     
    {     
        ClaimsFormsPageMessage.Text = "The server could not sign you in. Please input correct secure code.";     
        e.Cancel = true;     
    }     
}

private void EstablishSessionWithToken(SecurityToken securityToken)     
{     
    if (null == securityToken)     
    {     
        throw new ArgumentNullException("securityToken");     
    }     
    SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;     
    if (null == fam)     
    {     
        throw new ArgumentException(null, "FederationAuthenticationModule");     
    }

fam.SetPrincipalAndWriteSessionToken(securityToken);     
}

protected void signInControl_Authenticate(object sender, AuthenticateEventArgs e)     
{     
    SecurityToken token = null;     
    LoginControl formsLoginControl = sender as LoginControl;

if (null != (token = GetSecurityToken(formsLoginControl)))     
    {     
        EstablishSessionWithToken(token);     
        e.Authenticated = true;     
        base.RedirectToSuccessUrl();     
    }     
}

private SPIisSettings IisSettings     
{     
    get      
    {     
                
        SPWebApplication webApp = SPWebApplication.Lookup(new Uri(SPContext.Current.Web.Url));

SPIisSettings settings = webApp.IisSettings[SPUrlZone.Default];   
        return settings;   
    }   
}

private SecurityToken GetSecurityToken(LoginControl formsLoginControl)   
{   
    SecurityToken token = null;   
    SPIisSettings iisSettings = IisSettings;   
    Uri appliesTo = base.AppliesTo;

if (string.IsNullOrEmpty(formsLoginControl.UserName) ||   
        string.IsNullOrEmpty(formsLoginControl.Password))   
        return null;

SPFormsAuthenticationProvider authProvider = iisSettings.FormsClaimsAuthenticationProvider;     
    token = SPSecurityContext.SecurityTokenForFormsAuthentication(     
        appliesTo,     
        authProvider.MembershipProvider,     
        authProvider.RoleProvider,     
        formsLoginControl.UserName,     
        formsLoginControl.Password);

return token;   
}

代码的核心部分是执行登录的部分。SharePoint提供了SecurityTokenForFormsAuthentication专门供开发者处理Forms验证。我使用了SPIisSettings来取得当前Web App所使用的membership provider和roleship provider。

SPFormsAuthenticationProvider authProvider = iisSettings.FormsClaimsAuthenticationProvider;     
token = SPSecurityContext.SecurityTokenForFormsAuthentication(     
    appliesTo,     
    authProvider.MembershipProvider,     
    authProvider.RoleProvider,     
    formsLoginControl.UserName,     
    formsLoginControl.Password);

关联Default.aspx和FormsSignInPage

这部分比较简单,只要修改<%@ Page %>使它继承我们的FormsSignInPage就好了。

<%@PageLanguage="C#"AutoEventWireup="true"      
   Inherits="Morpheus.Demo.Pages.FormsSignInPage,FormsSignInPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=72d2bbe72853b8eb"      
   MasterPageFile="~/_layouts/simple.master"%>

然后我们就可以将我们的Assembly部署到GAC中,同时将default.aspx拷贝到_forms目录里。当执行登录时,如果用户没有输入正确的验证码,下面的错误会显示出来。

为SharePoint 2010中的FBA创建自定义登录页面的更多相关文章

  1. SharePoint 2013中以其他用户身份登录的WebPart(免费下载)

    在SharePoint 2013中微软并没有提供在SharePoint 2010中以其他用户身份登录的菜单,这对一般用户影响不大,但对于系统管理员或测试人员或特定人员(如在OA系统中的文员或秘书,常常 ...

  2. 在SharePoint 2010中创建网站的权限级别

    转:http://www.360sps.com/Item/CreatePermissionLevels.aspx 权限级别是SharePoint 2010新增加的功能,使我们对权限的设置又提高了一个层 ...

  3. SharePoint 2010 中创建超链接到Pop-Up对话框

    SharePoint 2010 中创建超链接到Pop-Up对话框         SharePoint 2010 推出了新式的带有阴影的弹出对话框,你感觉怎么样?我感觉倒是挺酷的.这样少打开了一个页面 ...

  4. 在Sharepoint 2010中启用Session功能的说明文档

    在Sharepoint 2010中启用Session功能的说明文档 开发环境:Windows 7系统,SharePoint Server 2010,Visual Studio 2010 按以下步骤进行 ...

  5. 在 SharePoint 2010 中访问数据

    转:http://blog.banysky.net/?p=81001 数据访问的关键方法有哪些? | 使用查询类 | 使用 SPQuery | 使用 SPSiteDataQuery | 使用 LINQ ...

  6. VSTO学习笔记(四)从SharePoint 2010中下载文件

    原文:VSTO学习笔记(四)从SharePoint 2010中下载文件 上一次我们开发了一个简单的64位COM加载项,虽然功能很简单,但是包括了开发一个64位COM加载项的大部分过程.本次我们来给CO ...

  7. 关于SharePoint 2010中不能使用AjaxControlToolkit的解决办法

    因为项目中有一个需求需要使用calendar控件,而且样式要和Reporting Service中的尽量一致,搜索了很久发现还是微软的AjaxControlToolkit提供的CalendarExte ...

  8. SharePoint 2010中重置windows 活动目录(AD)域用户密码的WebPart(免费下载)

    由于SharePoint 2013推出不久,并非所有的企业都会升级到SharePoint 2013的,毕竟升级不是打打补丁这么简单,更多的企业还是使用Sharepoint 2010版本的,因此本人自行 ...

  9. 在SharePoint 2010中部署RBS (转)

    一.RBS(Remote BLOB Storage)简单介绍 在SharePoint的大部分企业应用案例中,SharePoint都是要承担着非常繁重的文件管理工作,这些文件类型包含了Word文档,Ex ...

随机推荐

  1. Sublime Text Packages Control 安装

    一.简单的安装方法 使用Ctrl+`快捷键或者通过View->Show Console菜单打开命令行,粘贴如下代码: import urllib.request,os; pf = 'Packag ...

  2. HDU 4122 Alice's mooncake shop

    单调队列,裸的!!坑死了,说好的“All the orders are sorted by the time in increasing order. 呢,我就当成严格上升的序列了,于是就各种错.测试 ...

  3. iOS 创建上线证书

    1.制作上线证书需要准备一个付费的账号(99$),登陆https://developer.apple.com在最上方的位置点击Member Center进入登陆界面,在登陆界面输入付费的账号和密码进入 ...

  4. png图片的loading旋转

    img{ animation:rotate 1s linear infinite; -webkit-animation:rotate 1s linear infinite; } @keyframes ...

  5. Baby Ming and Matrix games(dfs计算表达式)

    Baby Ming and Matrix games Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  6. POJ 2420 A Star not a Tree? (计算几何-费马点)

    A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3435   Accepted: 172 ...

  7. 设计师Yoyo:为用户设计产品,让他们生活更美好

    Yoyo设计走过的路:纽约爱立信,西雅图美国在线,硅谷雅虎,ATT,深圳腾讯,华为:Yoyo不仅是顶级的交互体验设计师,还是很Open的知识分享者,从职业选择,以及对年轻人的建议几个角度,摘录他的文章 ...

  8. Cassandra - Non-system keyspaces don't have the same replication settings, effective ownership information is meaningless

    In cassandra 2.1.4, if you run "nodetool status" without any keyspace specified, you will ...

  9. Devexpress之barManager控件属性

    隐藏菜单栏左边的竖线和右边的箭头? 1.隐藏菜单栏上右边的箭头属性设置:OptionsBar=>>AllowQuickCustomization=False 2.隐藏菜单栏左边的竖线属性设 ...

  10. css3文本效果

    CSS3 包含多个新的文本特性. 在本章中,您将学到如下文本属性: 1. text-shadow 2. word-wrap 浏览器支持 Internet Explorer 10.Firefox.Chr ...