1

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:

  1. Invokes the OnSessionSecurityTokenCreated method to raise the SessionSecurityTokenCreated event
  2. Invokes the AuthenticateSessionSecurityToken method on SPFederationAuthenticationModule.Current to set the thread principal and then write the session cookie.

Some other points to note are:

  1. This 20 second login time also occurs for the default sharepoint fba page (/_forms/default.aspx)
  2. 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.

0

I managed to shave about 13 seconds off the login process by resolving the following ULS log entry.

3/30/2016 11:08:53.71 w3wp.exe (0x2448) 0x1148 SharePoint Foundation Topology 8321 Critical A certificate validation operation took 23141.9482 milliseconds and has exceeded the execution time threshold. If this continues to occur, it may represent a configuration issue. Please see http://go.microsoft.com/fwlink/?LinkId=246987 for more details. bc926d9d-52af-f0fb-b2ae-236a27cd54f1

So, SharePoint uses certificates to sign security tokens that are issued by the Security Token Service (STS). Like all certificates, the validity of the STS certificate has to be verified periodically to make sure that the certificate has not been revoked. By default, the root certificate in the chain is not added to the Trusted Root Certificate Authorities store of the SharePoint servers. Because of this, the certificate revocation list (CRL) check for the certificate is performed over the Internet which is not possible on our WFE server.

I resolved this by exporting the root cert, on the WFE server, using

$rootCert = (Get-SPCertificateAuthority).RootCertificate 
$rootCert.Export("Cert") | Set-Content C:\SharePointRootAuthority.cer -Encoding byte

And then importing the cert into the Trusted Root Certification Authorities store using the certificates mmc snapin.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.