Wednesday, August 24, 2011

Enabling Forms-based authentication on a SharePoint 2010 site


The easiest out-of-the-box solution is to use the Asp.NET SQL Membership Provider as the repository for the forms-based accounts.
The ASP.NET SQL Membership Provider does not come with a UI for managing/creating users and accounts. A custom solution or a third-party tool is usually used for this approach, in this example I use the
Codeplex FBA Pack  you can download here http://sharepoint2010fba.codeplex.com/, because it offers:
  • a user creation web part
  • a password recovery web part
  • a password reset web part
  • code is available for customization
  • tools for admin management of users

Installation steps

1. Create the ASP.NET SQL Membership Provider

This membership provider comes with the .NET Framework 2.0 and up and can be installed by launching the following tool:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql.exe

Leave all default settings in, type in the correct SQL Server name that will host this membership database and leave the database name to be “default”. This will create a new database called “aspnetdb” on your SQL Server.

2. Create a new forms-based web application that will host your new site collection

You can either create a single web application with both Windows and Forms-based authentication enabled on it, or the better approach is to create a web application with integrated Windows authentication enabled in the Default zone and then extend it onto another port, with Forms-based and anonymous in the Internet zone. This way, admins and a restricted number of internal users can access the   application with their Windows accounts, while the Internet zone can be accessed only via forms-based logins:


Navigate to Central Administration > Application Management > Manage Web Applications > New.
On the new “Create New Web Application” popup, pick “Claims Based Authentication”. Leave Windows/NTLM on and save.
Once your web application is created, click Extend in the Web Applications List Ribbon, while having the newly created web application selected. Chose a similar port and un-check NTLM and type in the new membership and role provider names:





You must enable anonymous access, because at least two of your new pages have to allow anonymous.
Let's call the two new pages "CreateMember.aspx" and "RecoverPassword.aspx". These two pages must be available without being logged in.
In case the out of-the-box login page is to be replaced with a custom one, a third page needs to be created that allows anonymous as well.

Create the site collection and set a Windows account as the site collection administrator. Once there are FBA accounts available, we can set the site collection administrator for the extended Internet zone application.

3. Bind the extended web application to the membership provider

Instructions can be found on a variety of blogs and also on msdn:

web.config settings need to be made in three locations: 
  • on the extended web application (1)
  • in Central Administration and (2)
  • in the Secure Token Service (3)
(1)  
  • Replace  <add key="AspNetSqlMembershipProvider" value="%" /> with  <add key="MyAspNetSqlMembershipProvider" value="%" /> - This setting will ensure that the People Picker control will allow admins the option of searching/adding a new user to SharePoint from the new membership provider.
  • Replace the membership provider/ role provider sections with:

    <roleManager enabled="true" cacheRolesInCookie="false" cookieName=".ASPXROLES" cookieTimeout="30" cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="All" defaultProvider="MyAspNetSqlRoleProvider" createPersistentCookie="false" maxCachedResults="25">
    <providers>
    <clear />
    <add connectionStringName="aspnetdb" applicationName="/" name="MyAspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <add applicationName="/" name="AspNetWindowsTokenRoleProvidertype="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
    </providers>
    </roleManager>
    <membership defaultProvider="i" userIsOnlineTimeWindow="15" hashAlgorithmType="">
    <providers>
    <clear />
    <add connectionStringName="aspnetdb" enablePasswordRetrieval="false" enablePasswordReset="true"  passwordAttemptWindow="10" applicationName="/" requiresUniqueEmail="true" passwordFormat="Hashed" name="MyAspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
    </providers>
    </membership>
  • Add the following connection string after <configSections>
  • <connectionStrings> <add name="aspnetdb" connectionString="data source=MOSS2010;Initial Catalog=aspnetdb;Integrated Security=SSPI;" providerName="System.Data.SqlClient" /></connectionStrings>
(2)

  • Add the following connection string after <configSections>
  • <connectionStrings> <add name="aspnetdb" connectionString="data source=MOSS2010;Initial Catalog=aspnetdb;Integrated Security=SSPI;" providerName="System.Data.SqlClient" /></connectionStrings>
  • <roleManager enabled="true" cacheRolesInCookie="false" cookieName=".ASPXROLES" cookieTimeout="30" cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="All" defaultProvider="AspNetWindowsTokenRoleProvider" createPersistentCookie="false" maxCachedResults="25">
    <providers>
    <clear />
    <add connectionStringName="aspnetdb" applicationName="/" name="MyAspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </providers>
    </roleManager>
    <membership defaultProvider="MyAspNetSqlMembershipProvider" userIsOnlineTimeWindow="15" hashAlgorithmType=""><providers>
    <clear />
    <add connectionStringName="aspnetdb" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" passwordAttemptWindow="10" applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed" name="MyAspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </providers>
    </membership>
(3)

  • Add the following connection string after <configSections>
  • <connectionStrings> <add name="aspnetdb" connectionString="data source=MOSS2010;Initial Catalog=aspnetdb;Integrated Security=SSPI;" providerName="System.Data.SqlClient" /></connectionStrings>
  • Add the section below:
    <system.web>
    <membership>
    <providers>
    <add connectionStringName="aspnetdb" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" passwordAttemptWindow="10" applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed" name="MyAspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </providers>
    </membership>
    <roleManager enabled="true">
    <providers>
    <add connectionStringName="aspnetdb" applicationName="/" name="MyAspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </providers>
    </roleManager>
You should now be able to navigate to your new site collection and you should be prompted for credentials -
"/_forms/default.aspx" is the out-of-the-box login for forms-authenticated users.
In order to log in here, at least one forms account needs to be created in the database (aspnetdb) and added to SharePoint as a user. You will do this from the new CreateMember.aspx page, once it is set up.

4. Install the Codeplex FBA app


Pre-requisites for installing the FBA Pack:
o   site collection features: "Publishing Infrastructure" should be activated
o   site features: “SharePoint Server Publishing” features should be activated
Follow the installation instructions on Codeplex.

Create a new document library called 'Public' with two pages  "CreateMember.aspx" and "RecoverPassword.aspx", each with the corresponding FBA Pack webpart on it. Enable anonymous access on lists and document libraries only and enable it on the 'Public' library only. Make sure both pages have at least one published major version. You should be able to navigate to these pages without being signed in.
Use the CreateMember.aspx page to create the first generic admin FBA account. Log in as Windows site collection administrator and make this new FBA account site collection admin on the extended web application.