I no longer work at Microsoft, so please don't bother leaving a comment here or trying to contact me through my MSDN blog.
You can find my new blog at http://www.technologytoolbox.com/blog/jjameson. My new site also provides copies of all posts from my MSDN blog.
I thought it would be helpful to share my step-by-step procedures for manually configuring claims-based authentication in SharePoint Server 2010 using an "ASP.NET database" and corresponding membership and role providers.
Note that the following TechNet article provides some of the steps for configuring claims-based authentication in SharePoint Server 2010 (using the LDAP provider instead of the ASP.NET SQL providers):
I had originally intended this post to simply serve as a precursor to my next post, but during the process of writing this post, I realized that there are many pieces lacking from the TechNet article. For example, if you use the current PowerShell script provided in the above TechNet article, you end up with a Web application that doesn't support Search (because it does not enable both Windows authentication as well as Forms-Based Authentication).
In this post, I'll share a "real world" process for creating and configuring a Web application in SharePoint Server 2010 using claims-based authentication.
In the following procedures, assume that we are configuring the public Internet site for Fabrikam Technologies (my favorite fictitious manufacturing company) and we want to provide the ability for customers and partners to login and access personalized content. User accounts for customers and partners are stored in a SQL Server database (FabrikamDemo).
[User accounts for Fabrikam employees are stored in Active Directory. Consequently, Fabrikam employees will not login using forms-based authentication. Rather, in order to author content and manage the site, Fabrikam employees authenticate with the site using Windows authentication (in other words, via the generic login window that varies slightly depending on the Web browser being used).]
The relevant service accounts for claims-based authentication are listed in the following table.
[Assume that Fabrikam has established an "extranet" Active Directory domain which will be used to host the SharePoint farm. In order to allow Fabrikam employees to authenticate with their internal domain (FABRIKAM) credentials, a one-way trust is established from the EXTRANET domain to the FABRIKAM domain.]
Configuring claims-based authentication using a SQL Server database consists of the following high-level steps:
In this step, the database for storing ASP.NET membership and role information is created and the two service accounts specified in Table 1 are added to to the appropriate database roles.
cd %WinDir%\Microsoft.NET\Framework\v2.0.50727
aspnet_regsql.exe
Important Database access must be granted to both the service account used for the Fabrikam Web application and the SharePoint farm account. If the SharePoint farm account does not have access to the database, the Security Token Service used for claims-based authentication will be unable to validate the credentials.
Note The reason the database roles are different between the two service accounts is because the SharePoint farm account only needs permissions to validate credentials and determine role membership, whereas the Fabrikam Web application service account needs additional permissions in order to support other scenarios for the Fabrikam site (e.g. "Change Password" and "Reset Password").
In this step, the Web application and initial site collection are created.
$ErrorActionPreference = "Stop" $appPoolUserName = "EXTRANET\svc-web-fabrikam" $membershipProviderName = "FabrikamSqlMembershipProvider" $roleProviderName = "FabrikamSqlRoleProvider" $webAppName = "SharePoint - www.fabrikam.com80" $webAppUrl = "http://www.fabrikam.com" $contentDatabaseName = "WSS_Content_FabrikamDemo" $appPoolName = $webAppName Write-Debug "Get service account for application pool ($appPoolUserName)..." $appPoolAccount = Get-SPManagedAccount -Identity $appPoolUserName -EA 0 if($appPoolAccount -eq $null) { Write-Host "Registering managed account ($appPoolUserName)..." Write-Debug "Get credential ($appPoolUserName)..." $appPoolCredential = Get-Credential $appPoolUserName $appPoolAccount = New-SPManagedAccount -Credential $appPoolCredential } $windowsAuthProvider = New-SPAuthenticationProvider $formsAuthProvider = New-SPAuthenticationProvider ` -ASPNETMembershipProvider $membershipProviderName ` -ASPNETRoleProviderName $roleProviderName $authProviders = $windowsAuthProvider, $formsAuthProvider $webApp = New-SPWebApplication -Name $webAppName -AllowAnonymousAccess ` -ApplicationPool $appPoolName -AuthenticationMethod "NTLM" ` -ApplicationPoolAccount $appPoolAccount -Url $webAppUrl -Port 80 ` -AuthenticationProvider $authProviders -DatabaseName $contentDatabaseName
$ErrorActionPreference = "Stop" $webAppUrl = "http://www.fabrikam.com" $siteName = "Fabrikam" $siteDescription = "Public Internet site for Fabrikam Technologies" $siteTemplate = "BLANKINTERNETCONTAINER#0" $ownerAlias = $env:USERDOMAIN + "\" + $env:USERNAME $siteUrl = $webAppUrl + "/" New-SPSite $siteUrl -OwnerAlias $ownerAlias -Name $siteName ` -Description $siteDescription -Template $siteTemplate
When using Forms-Based Authentication, it is important to secure the communication between the clients and the Web servers (in order to avoid sending user credentials in clear text over the network). In this section, the Web application is modified to support both HTTP and HTTPS, and the corresponding SSL certificate is configured for the Web site.
In addition to enabling anonymous access on the Web application, the root Web of the site collection must also be configured to enable anonymous access.
$ErrorActionPreference = "Stop" Add-PSSnapin Microsoft.SharePoint.PowerShell -EA 0 $webUrl = "http://www.fabrikam.com/" function EnableAnonymousAccess( [Microsoft.SharePoint.SPWeb] $web) { Write-Debug "Enabling anonymous access on site ($($web.Url))..." $anonymousPermissionMask = [Microsoft.SharePoint.SPBasePermissions]::Open ` -bor [Microsoft.SharePoint.SPBasePermissions]::ViewFormPages ` -bor [Microsoft.SharePoint.SPBasePermissions]::ViewListItems ` -bor [Microsoft.SharePoint.SPBasePermissions]::ViewPages ` -bor [Microsoft.SharePoint.SPBasePermissions]::ViewVersions if ($web.AnonymousPermMask64 -eq $anonymousPermissionMask) { Write-Debug ` "Anonymous access is already enabled on site ($($web.Url))." return; } if ($web.HasUniqueRoleAssignments -eq $false) { $web.BreakRoleInheritance($true); } $web.AnonymousPermMask64 = $anonymousPermissionMask; $web.Update(); Write-Host -Fore Green ` "Successfully enabled anonymous access on site ($($web.Url))." } $DebugPreference = "SilentlyContinue" $web = Get-SPWeb $webUrl $DebugPreference = "Continue" EnableAnonymousAccess $web
In order to complete the configuration of claims-based authentication, it is necessary to modify the Web.config files for the following sites:
Important Before you make changes to the Web.config file, make a copy of it by using a different name (for example, “Web - Copy.config”), so that if a mistake is made in the file, you can delete it and use the original file.
Note If you see a dialog box that says that Windows cannot open the file, click Select the program from a list, and then click OK. In the Open With dialog box, click Notepad, and then click OK.
</configSections>
<connectionStrings> <add name="FabrikamDemo" connectionString="Server={databaseServer};Database=FabrikamDemo;Integrated Security=true" /> </connectionStrings>
Important Be sure to replace the {databaseServer} placeholder in the connection string with the name of the database server.
<add name="FabrikamSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" applicationName="Fabrikam Demo Site" connectionStringName="FabrikamDemo" />
<add name="FabrikamSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" applicationName="Fabrikam Demo Site" connectionStringName="FabrikamDemo" passwordFormat="Hashed" />
<configuration>
<connectionStrings> <add name="FabrikamDemo" connectionString="Server={databaseServer};Database=FabrikamDemo;Integrated Security=true" /> </connectionStrings> <system.web> <membership> <providers> <add name="FabrikamSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" applicationName="Fabrikam Demo Site" connectionStringName="FabrikamDemo" passwordFormat="Hashed" /> </providers> </membership> <roleManager> <providers> <add name="FabrikamSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" applicationName="Fabrikam Demo Site" connectionStringName="FabrikamDemo" /> </providers> </roleManager> </system.web>
Warning Do not overwrite any existing entries in this Web.config file.
<add name="FabrikamSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" applicationName="Fabrikam Demo Site" connectionStringName="FabrikamDemo" enablePasswordReset="true" enablePasswordRetrieval="false" passwordFormat="Hashed" requiresQuestionAndAnswer="true" requiresUniqueEmail="true" />
The final step is to validate the Web application works as expected when using both Forms-Based Authentication and Windows authentication.
Note This is discussed in more detail in the following blog post: Be "In the Zone" to Avoid Entering Credentials http://blogs.msdn.com/jjameson/archive/2007/03/22/be-in-the-zone-to-avoid-entering-credentials.aspx
In my next post, I explain how to create a custom Web Part that can be used to provide a "branded" login page (instead of the generic "Sign In" page provided out-of-the-box in SharePoint Server 2010).