为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目录里。当执行登录时,如果用户没有输入正确的验证码,会显示出错误来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值