I recently implemented Forms-Based Authentication (FBA) in MOSS 2007 and had it working great. Unfortunately we had to reinstall the system and I actually had more issues getting FBA to work correctly on the reinstall than I did the first time. It turned out that the issue was mixing different implementation methods that counteracted each other. The simplest way to configure FBA is to edit the machine.config file on the server (%WINDOWS%\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config) and change the LocalSqlServer connection string to the ASPNETDB user store or other database with the user information. This takes advantage of the pre-configured AspNetSqlMembershipProvider and AspNetSqlRoleProvider in the <system.web><membership> and <roleManager> sections. The AspNetSqlMembershipProvider and AspNetSqlRoleProvider sections normally include something similar to:

<system.web>
  <membership>
    <providers>
      <add
        name="AspNetSqlMembershipProvider"
        type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        connectionStringName="LocalSqlServer"
        enablePasswordRetrieval="false"
        enablePasswordReset="true"
        requiresQuestionAndAnswer="true"
        applicationName="/"
        requiresUniqueEmail="false"
        passwordFormat="Hashed"
        maxInvalidPasswordAttempts="5"
        minRequiredPasswordLength="7"
        minRequiredNonalphanumericCharacters="1"
        passwordAttemptWindow="10"
        passwordStrengthRegularExpression=""
      />
    </providers>
  </membership>
  <roleManager>
    <providers>
      <add
        name="AspNetSqlRoleProvider"
        connectionStringName="LocalSqlServer"
        applicationName="/" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
      />
      <add
        name="AspNetWindowsTokenRoleProvider"
        applicationName="/"
        type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
      />
    </providers>
  </roleManager>
</system.web>

The important thing to note is the connectionStringName attributes that are configured to use LocalSqlServer. If you change the settings for LocalSqlServer then the membership and roleManager will automatically use the updated setting.

Many SharePoint FBA guides recommend changing the web.config for the web application. This is still a good recommendation however if you choose this implementation method, be sure not to use both methods and edit both the machine.config and web.config. For example, I added the following to my web.config:

<system.web>
  <!-- This caused the SharePoint authentication to fail.
       I already knew these providers were configured in the machine.config,
       so I simply referenced them. -->
  <membership defaultProvider="AspNetSqlMembershipProvider" />
  <roleManager defaultProvider="AspNetSqlRoleProvider" enabled="true" />

What happened is that I tried to login and I would see an "Access Denied" screen. I double-checked the Site collection administrators in the SharePoint Central Administration and it was set properly but I was unable to access any content using FBA. Eventually it dawned on me to remove the configuration from the web.config and simply try the settings in Central Administration under Application Management \ Authentication providers. Once I removed the redundant information in web.config, FBA worked again.

Technorati tags: , ,