zoukankan      html  css  js  c++  java
  • 为SharePoint 2010中的FBA创建自定义登录页面

    为SharePoint 2010中的FBA创建自定义登录页面
    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目录里。当执行登录时,如果用户没有输入正确的验证码,会显示出错误来。

    转自:http://www.mosscode.com/thread-102-1-1.html

  • 相关阅读:
    提取RDLC reporting相关dll的方式,打包客户端时需要用
    VS2012程序打包部署详解
    快速打包你的应用程序——Inno Setup
    "RDLC"报表-参数传递及主从报表
    如何在多个页中显示行标题和列标题 (Reporting Services)
    编译cocos2d-x 4.0版本
    2080Ti评测结果
    (转)u3d设计模式
    java基础知识(一)
    Java8新特性学习(一)--lambda表达式
  • 原文地址:https://www.cnblogs.com/poissonnotes/p/2064854.html
Copyright © 2011-2022 走看看