I've searched online at all different documents regarding FBA custom login page for Sharepoint 2010. Nearly everyone I have found, either shows you a custom page, adds a login control and no code behind, and the page works. (I've tried this and can confirm it works). However I need to have code behind as I'm testing if a user requires them to change their password.
Using reflecter I've been able to create my login page using FormsSignInPage as a base class. My OnLogginIn event and OnAUthenticate micks what microsoft does in their code in a round about way. However, once the user has been authenticated I was hoping to call my custom membership provider find out if the user needs to change thier password and open a pop up dialog pointing to a layouts page that allows them to change thier password. If they change their password, the user is redirected to site, if they cancel or close the dialog, the code logs them out as they are required to change thier password to continue using the site.
Using my code, and removing any redirects, I expected my code to authenticate and update a label on the page saying "User to change password" or "User doesn't need to change password". However with my code, even without any redirects on the page, it still redirects the user to the original page they were heading to, before needing to login. I cannot work out why, how, or what I need to change. My code is shown below which might help other people out when creating their own page.
ASP.NET
<asp:Content ID="Content2" ContentPlaceHolderId="PlaceHolderMain" runat="server">
<asp:Literal ID="litInfo" runat="server"/>
<center>
<div id="content" class="rounded" style="width: 300px; height: auto; margin-top: 15%; background:black;">
<!--//Standard Login control with set custom MembershipProvider FBAMembershipProvider -->
<asp:Login ID="hlsignInControl"
style="width: 250px"
FailureText="<%$Resources:wss,login_pageFailureText%>"
runat="server"
DisplayRememberMe="true"
TextBoxStyle-Width="250px"
RememberMeSet="false"
LoginButtonStyle-CssClass="ms-buttonheightwidth"
UserNameLabelText="User name"
TextLayout="TextOnTop"
PasswordLabelText="Password"
LabelStyle-Font-Bold="false"
LabelStyle-Font-Size="Large"
LabelStyle-ForeColor="White"
LabelStyle-Font-Names="Calibri"
LabelStyle-CssClass="ms-standardheader ms-inputformheader"
TextBoxStyle-CssClass="ms-input"
CheckBoxStyle-Font-Bold="false"
CheckBoxStyle-Font-Names="Calibri"
CheckBoxStyle-ForeColor="White"
CheckBoxStyle-CssClass="ms-standardheader ms-inputformheader"
CheckBoxStyle-Font-Size="Large"
FailureTextStyle-Wrap="true"
FailureTextStyle-Font-Names="Calibri"
FailureTextStyle-Font-Size="Small"
LoginButtonStyle-Font-Names="Calibri"
LoginButtonStyle-Font-Size="Large"
TitleText=""
TitleTextStyle-ForeColor="White"
TitleTextStyle-Font-Bold="true"
TitleTextStyle-Wrap="true"
TitleTextStyle-Font-Names="Calibri"
TitleTextStyle-Font-Size="Larger"
OnAuthenticate = "hlsignInControl_Authenticate"
OnLoggingIn = "hlsignInControl_LoggingIn"
OnLoggedIn = "hlsignInControl_LoggedIn"/>
</div>
</center>
<!-- //Required from inherited class "FormsSignInPage"-->
<SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" ID="ClaimsFormsPageMessage" Visible="false" />
</asp:Content>
C# Code
using System;
using System.IdentityModel.Tokens;
using System.Web.UI.WebControls;
using SharePoint.FBA.Code.HelperClasses;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Administration.Claims;
using Microsoft.SharePoint.IdentityModel;
using Microsoft.SharePoint.IdentityModel.Pages;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;
namespace SharePoint.FBA.Layouts.Login
{
public partial class Login : FormsSignInPage
{
protected override void OnLoad(EventArgs e)
{
//base.OnLoad(e);
hlsignInControl.Focus();
CheckBox box = null;
if (SPSecurityTokenServiceManager.Local.UseSessionCookies && ((box = this.hlsignInControl.FindControl("RememberMe") as CheckBox) != null))
{
box.Enabled = false;
box.Visible = false;
}
}
protected void hlsignInControl_LoggedIn(object sender, EventArgs e)
{
var s = "I'm Logged in now what!";
}
protected void hlsignInControl_Authenticate(object sender, System.Web.UI.WebControls.AuthenticateEventArgs e)
{
bool flag = false;
var loginControl = sender as System.Web.UI.WebControls.Login;
SecurityToken securityToken = null;
if (loginControl == null)
{
throw new ArgumentException(null, "sender");
}
using (new SPMonitoredScope("Login.Authenticate: Retrieve Security token and establish session."))
{
securityToken = this.GetSecurityToken(loginControl);
if (securityToken == null)
{
flag = false;
}
else
{
SPSessionTokenWriteType writeDefaultCookie = SPSessionTokenWriteType.WriteDefaultCookie;
if (!SPSecurityTokenServiceManager.Local.UseSessionCookies && !loginControl.RememberMeSet)
{
writeDefaultCookie = SPSessionTokenWriteType.WriteSessionCookie;
}
EstablishSessionWithToken(securityToken, writeDefaultCookie);
flag = true;
}
}
e.Authenticated = flag;
if (flag)
{
var mem = (MyMembershipProvider)Utils.BaseMembershipProvider();
HLMembershipUser memUser;
memUser = (MyMembershipUser)mem.GetUser(loginControl.UserName, true);
if (memUser.IsPasswordChanged)
{
litInfo.Text = "Password need Changing";
//
}
else
{
litInfo.Text = "Password fine";
//Removed this line to prevent redirect, although it redirects anyway.
//RedirectToSuccessUrl();
}
}
}
protected void hlsignInControl_LoggingIn(object sender, System.Web.UI.WebControls.LoginCancelEventArgs e)
{
var login = sender as System.Web.UI.WebControls.Login;
if (login == null)
{
throw new ArgumentException(null, "sender");
}
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(login.Password))
{
ClaimsFormsPageMessage.Text = "The server could not sign you in. The password cannot be emtpy.";
e.Cancel = true;
}
}
private SecurityToken GetSecurityToken(System.Web.UI.WebControls.Login loginControl)
{
SPIisSettings iisSettings = IisSettings;
Uri appliesTo = new Uri(SPContext.Current.Web.Url);
if (!iisSettings.UseClaimsAuthentication || !iisSettings.UseFormsClaimsAuthenticationProvider)
{
throw new InvalidOperationException();
}
if (string.IsNullOrEmpty(loginControl.UserName) || (loginControl.Password == null))
{
return null;
}
SPFormsAuthenticationProvider formsClaimsAuthenticationProvider =
iisSettings.FormsClaimsAuthenticationProvider;
return SPSecurityContext.SecurityTokenForFormsAuthentication(appliesTo,
formsClaimsAuthenticationProvider.
MembershipProvider,
formsClaimsAuthenticationProvider.RoleProvider,
loginControl.UserName, loginControl.Password,
loginControl.RememberMeSet);
}
private SPIisSettings IisSettings
{
get {
SPWebApplication webApp = SPWebApplication.Lookup(new Uri(SPContext.Current.Web.Url));
SPIisSettings settings = webApp.IisSettings[SPContext.Current.Site.Zone];
return settings;
}
}
private void EstablishSessionWithToken(SecurityToken securityToken, SPSessionTokenWriteType sessionCookie)
{
if (securityToken == null)
{
throw new ArgumentNullException("securityToken");
}
SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;
if (fam == null)
{
throw new ArgumentException(null, "FederationAuthenticationModule");
}
SPSecurity.RunWithElevatedPrivileges(() => fam.SetPrincipalAndWriteSessionToken(securityToken));
}
}
}
