设为首页 收藏本站
查看: 701|回复: 0

[经验分享] 为SharePoint 2010中的FBA创建自定义登录页面

[复制链接]

尚未签到

发表于 2015-9-28 10:00:55 | 显示全部楼层 |阅读模式
为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官方支持,如果你要用在你的项目中,风险自负。 DSC0000.png
  创建自定义登录页面
  如果我们留意一下会发现,默认的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,之后才能成功登录。页面运行的效果如下:
DSC0001.png
  当然,此时验证码还没有作用,我们必须写一些代码来实现验证的功能。
  创建Code Behind类实现验证和登录功能
  接下来是为default.aspx实现一个类来实现验证和登录功能。在项目中添加一个类,可以命名为FormsSignInPage。接着是添加一些引用,首先是Microsoft.SharePoint.dll。由于我们要处理Claims,System.IdentityModel.dll和Microsoft.IdentityModel.dll也是必须的。另外,SharePoint有一个自己的处理Claims的Module,Microsoft.SharePoint.IdentityModel.dll。添加对它的引用时,需要定位到它所在的目录。引用添加完,看起来像下面这样。
DSC0002.png
  我们的类,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目录里。当执行登录时,如果用户没有输入正确的验证码,下面的错误会显示出来。

  这个登录页面的代码可以从这里下载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-119834-1-1.html 上篇帖子: SharePoint 2013 APP 开发示例 (四)JQuery访问REST 下篇帖子: Microsoft Office Sharepoint Server 2007开发系列课程(视频课程讲师:鞠海洋)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表