We have a SharePoint 2013 implementation in which our web application is using Forms Based Authentication (FBA).
There are 2 servers in the farm. A web front end server that resides in a DMZ and a SQL server that resides within the corporate network. A firewall separates them.
We are using SQL Authentication.
We created a custom FBA sign in page because there was a requirement to force the user to change their password after their first successful login. Our solution was based on the following article. (How to create a custom FBA login Page that forces user to change password and view license agreement if required).
It works but the problem we face is that, intermittently, it takes 20 seconds or more to complete the sign in process. This is not associated with APP pool or iis resets.
The code in question is:
private void SignInUser()
{
SecurityToken token = SPSecurityContext.SecurityTokenForFormsAuthentication
(new Uri(SPContext.Current.Web.Url),
GetMembershipProvider(SPContext.Current.Site),
GetRoleProvider(SPContext.Current.Site),
_userName,
_password, SPFormsAuthenticationOption.None);
SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;
fam.SetPrincipalAndWriteSessionToken(token, SPSessionTokenWriteType.WriteSessionCookie);
SPUtility.Redirect(System.Web.Security.FormsAuthentication.DefaultUrl, SPRedirectFlags.UseSource, this.Context);
}
public static string GetMembershipProvider(SPSite site)
{
// get membership provider of whichever zone in the web app fba isenabled
SPIisSettings settings = GetFbaIisSettings(site);
if (settings == null) return null;
return settings.FormsClaimsAuthenticationProvider.MembershipProvider;
}
public static string GetMembershipProvider(SPSite site)
{
// get membership provider of whichever zone in the web app is fba enabled
SPIisSettings settings = GetFbaIisSettings(site);
if (settings == null) return null;
return settings.FormsClaimsAuthenticationProvider.MembershipProvider;
}
private static SPIisSettings GetWindowsIisSettings(SPSite site)
{
SPIisSettings settings;
try
{
settings = site.WebApplication.IisSettings[site.Zone];
if (settings.UseWindowsClaimsAuthenticationProvider)
return settings;
}
catch
{
// expecting errors here so do nothing
}
foreach (SPUrlZone zone in Enum.GetValues(typeof (SPUrlZone)))
{
try
{
settings = site.WebApplication.IisSettings[(SPUrlZone) zone];
if (settings.UseWindowsClaimsAuthenticationProvider)
return settings;
}
catch
{
// expecting errors here so do nothing
}
}
// return null if FBA not enabled
return null;
}
The code which takes the time is: fam.SetPrincipalAndWriteSessionToken(token, SPSessionTokenWriteType.WriteSessionCookie);
From my understanding this line of code does the following:
- Invokes the OnSessionSecurityTokenCreated method to raise the SessionSecurityTokenCreated event
- Invokes the AuthenticateSessionSecurityToken method on SPFederationAuthenticationModule.Current to set the thread principal and then write the session cookie.
Some other points to note are:
- This 20 second login time also occurs for the default sharepoint fba page (/_forms/default.aspx)
- It does not occur on a standalone dev machine.
For me this would indicate the bottleneck is network related.
Any help would be much appreciated.