Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Guide to create forms authentication on SharePoint (1 of 2)

4.60/5 (4 votes)
24 Jul 2008CPOL8 min read 1  
The first of two articles about the steps I took to create forms based authentication on SharePoint .

Introduction

This article records the steps I took to create forms based authentication in SharePoint assuming we already have a vanilla SharePoint site that uses Windows authentication. Only in some cases have I expanded the guide with explanations. So expect a fairly concise guide and forgive my brevity. Of course if you send me a request to expand certain parts, I will try my best to improve the article.

Assumptions

The article assumes we are using Windows SharePoint Services 2007 and Visual Studio 2008. Also, we will only use the SQL Server membership provider database (called application services) that is provided with .NET 2.0 and not the Shared Service Providers.

Why not use Shared Service Providers (SSP)? If all you want to do is have very basic forms authentication, then SSP is overkill (my opinion). Also SSP is only available with Office SharePoint Server or Project Server and not with the standard Windows SharePoint Services (WSS). Also I found too much evidence of failed attempts to get SSP working with forms based authentication. Nevertheless, I aim to cover this in my next article called Guide to create forms authentication on SharePoint (2 of 2).

Also, I should note that the solution provided in this article does not give you a user administration application. Once user administration becomes an important feature, you may want to consider using SSP.

The port numbers used in this article may not reflect your environment. We assume the default site uses port 80 and the Central Administration site uses port 19999.
I have included no code download and no images with this article. I did not produce any useful code apart from the displayed code snippets.

Create application services database

Use this wizard to create a database called AspNetSqlMembership on YOURDBSERVER.

re:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ aspnet_regsql.exe

Notes:

  • Default database name is aspnetdb, but rather use something specific like AspNetSqlMembership.
  • If you don’t have permission to create a database on the chosen server, ask the DBA to create one, add your NT account as a user and grant your user roles db_accessadmin plus all roles like aspnet_*_FullAccess. Then run wizard again.
  • Check to see what network user account is used in the IIS. See the identity tab in the application pool property pages. For the sake of this article, I assume the user is YOURDOMAIN\networkuser
  • Also ask DBA to add YOURDOMAIN\networkuser as a user and grant all roles like aspnet_*_FullAccess.
  • Default for application name is “/”. To change this, need to change data in table aspnet_Applications and the relevant entries in the config file below.

Create Users and Roles

Use the “ASP.NET Configuration” feature of VS2008 to quickly create users.

Steps:

  • From a development machine, create a new Web site using VS2008.
  • In the web.config file, change add
ASP.NET
<connectionStrings>
  <remove name="LocalSqlServer"/>
  <add name="LocalSqlServer" 
                 connectionString="Server=YOURDBSERVER;
                                  Integrated Security=SSPI;
                                  Database=AspNetSqlMembership;"
                 providerName="System.Data.SqlClient"/>
</connectionStrings>
  • Navigate to menu Website / ASP.NET Configuration.
  • Click on security. If an error occurs, you don’t have the right permissions, see first section above.
  • Create a role called Agent.
  • Create a user called user1. Note: The default password rules mandate the use of one or more non-alphanumeric characters. So include something like ! or #. This silly misunderstanding cost me a few hours already. If you don’t want to use non-alphanumeric, you will have to add a membership node to the above web.config file and specify your choice in the minRequiredNonalphanumericCharacters attribute. Then, you also need to change the value of this attribute in all cases below.
  • Add the Agent role to this user.

Using the “ASP.NET Configuration” feature of VS2008 only provided a quick method of creating users. Since this article does not provide a user administration application, I will recommend using SQL scripts to deploy users into production. There are other alternatives, but I want to move on with the main purpose of the article. Besides, once user administration becomes an important feature, you may want to consider using SSP.

Extend the Site

Extend your existing site to create a new Extranet site.

re:
Central Administration > Application Management > Create or Extend Web Application

Steps:

  • Enter site description as “AgentSite Extranet” if default site is called “AgentSite”.
  • I like to make the new port number meaningful. E.g. use port 10080 if default site is using port 80.
  • Set allow anonymous to true.
  • Change zone to Extranet.

Enable Full Exception Messages to Appear

By default, SharePoint will hide application exceptions and merely show a generic error message. Even though this behavior is preferred for production environments, we need to allow full exception messages to show in our development environment. Change this setting in the default site and the Extranet site. However, I have found that this setting has no effect on the Central Administration site.

re:
\\yourserver\c$\Inetpub\wwwroot\wss\VirtualDirectories\80\web.config
\\yourserver\c$\Inetpub\wwwroot\wss\VirtualDirectories\10080\web.config

Change the CallStack setting to true.

ASP.NET
<configuration>
  <SharePoint>
    <SafeMode  CallStack="true" 
 

Also turn off custom errors.

ASP.NET
<customErrors mode="Off" />

Central Administration to use New Provider

Edit the web config file of your Central Administration site to use the new membership provider and connection string. This change is required to allow an administrator to associate new users or roles to the Extranet site.

re:
\\yourserver\c$\Inetpub\wwwroot\wss\VirtualDirectories\19999\web.config

ASP.NET
<configuration>
  <connectionStrings>
    <add name="AgentSiteConnectionString" 
                connectionString="Server=YOURSERVER;Integrated Security=SSPI;
                                Database=AspNetSqlMembership;" 
                providerName="System.Data.SqlClient" />
  </connectionStrings>

ASP.NET
<configuration>
  <system.web>
    <membership defaultProvider="AgentSiteMembershipProvider">
      <providers>
        <remove name="AgentSiteMembershipProvider" />
        <add name="AgentSiteMembershipProvider" 
                type="System.Web.Security.SqlMembershipProvider, System.Web, 
                        Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
                connectionStringName="AgentSiteConnectionString" 
                enablePasswordRetrieval="false" 
                enablePasswordReset="true" 
                requiresQuestionAndAnswer="true" 
                applicationName="/" 
                requiresUniqueEmail="false" 
                passwordFormat="Hashed" 
                maxInvalidPasswordAttempts="5" 
                minRequiredPasswordLength="7" 
                minRequiredNonalphanumericCharacters="1" 
                passwordAttemptWindow="10" 
                passwordStrengthRegularExpression="" />
      </providers>
    </membership>
    <profile>
      <providers>
        <remove name="AgentSiteProfileProvider" />
          <add name="AgentSiteProfileProvider" 
                        connectionStringName="AgentSiteConnectionString" 
                        applicationName="/" 
                        type="System.Web.Profile.SqlProfileProvider, System.Web, 
                                Version=2.0.0.0, Culture=neutral,
                                PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
    </profile>
    <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
      <providers>
        <remove name="AgentSiteRoleProvider" />
        <add name="AgentSiteRoleProvider" 
                        connectionStringName="AgentSiteConnectionString" 
                        applicationName="/" 
                        type="System.Web.Security.SqlRoleProvider, System.Web, 
                                Version=2.0.0.0, Culture=neutral,
                                PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
    </roleManager>

It is very important that default role manager provider remain as "AspNetWindowsTokenRoleProvider". If you accidently make "AgentSiteRoleProvider" the default, you will not be able to log into Central Administration in the first place.

Extranet Site to use New Provider

Edit the web config file of your Extranet site to use the new membership provider and connection string.

re:
\\yourserver\c$\Inetpub\wwwroot\wss\VirtualDirectories\10080\web.config

ASP.NET
<configuration>
  <connectionStrings>
    <add name="AgentSiteConnectionString" 
                connectionString="Server=YOURSERVER;Integrated Security=SSPI;
                                Database=AspNetSqlMembership;" 
                providerName="System.Data.SqlClient" />
  </connectionStrings>

ASP.NET
<configuration>
  <system.web>
    <membership defaultProvider="AgentSiteMembershipProvider">
      <providers>
        <remove name="AgentSiteMembershipProvider" />
        <add name="AgentSiteMembershipProvider" 
                        type="System.Web.Security.SqlMembershipProvider, System.Web, 
                                        Version=2.0.0.0, Culture=neutral,
                                        PublicKeyToken=b03f5f7f11d50a3a"
                        connectionStringName="AgentSiteConnectionString" 
                        enablePasswordRetrieval="false" 
                        enablePasswordReset="true" 
                        requiresQuestionAndAnswer="true" 
                        applicationName="/" 
                        requiresUniqueEmail="false" 
                        passwordFormat="Hashed" 
                        maxInvalidPasswordAttempts="5" 
                        minRequiredPasswordLength="7" 
                        minRequiredNonalphanumericCharacters="1" 
                        passwordAttemptWindow="10" 
                        passwordStrengthRegularExpression="" />
      </providers>
    </membership>
    <profile>
      <providers>
        <remove name="AgentSiteProfileProvider" />
          <add name="AgentSiteProfileProvider" 
                              connectionStringName="AgentSiteConnectionString" 
                              applicationName="/" 
                              type="System.Web.Profile.SqlProfileProvider, System.Web, 
                                        Version=2.0.0.0, Culture=neutral,
                                        PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
    </profile>
    <roleManager enabled="true" defaultProvider="AgentSiteRoleProvider">
      <providers>
        <remove name="AgentSiteRoleProvider" />
        <add name="AgentSiteRoleProvider" 
                        connectionStringName="AgentSiteConnectionString" 
                        applicationName="/" 
                        type="System.Web.Security.SqlRoleProvider, System.Web, 
                                        Version=2.0.0.0, Culture=neutral,
                                        PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
    </roleManager>

Change the Authentication Settings for the Extranet

The authentication settings of the Extranet site must be changed to use the new membership provider and role provider.

re:
Central Administration > Application Management > Authentication Providers

Steps:

  • Click on Extranet
  • Set authentication type to forms.
  • Enable anonymous must be ticked.
  • Make the membership provider name AgentSiteMembershipProvider.
  • Make the role manager name AgentSiteRoleProvider.
  • Do not enable client integration.

Additional step: Since the web.config file was copied from the default site, the impersonation setting should be removed.

Open
\\yourserver\c$\Inetpub\wwwroot\wss\VirtualDirectories\10080\web.config
and change
ASP.NET
<authentication mode="Forms">
  <forms loginUrl="/_layouts/login.aspx" />
</authentication>
<identity impersonate="true" >
To
ASP.NET
<authentication mode="Forms">
  <forms loginUrl="/_layouts/login.aspx" />
</authentication>
<!--identity impersonate="true" /-->

The last step was necessary to avoid various permission problems. With impersonation, the forms authentication site then runs as YOURSERVER\IUSR_YOURSERVER and this user does not have permission to re-compile binaries. When a binary cannot be re-compiled using the IUSR account, the site reports a 403 FORBIDDEN error. If you find that your Extranet site works most of the times and only occasionally reports a 403, you most likely have this problem. I used Sysinternals Procmon.exe to see what account was attempting to access the bin folder and was resulting in an ACCESS DENIED status.

Permit Users in Role to Access Extranet

An administrator can now associate the new role with the Extranet site.

re:
Central Administration > Application Management > Policy for Web Application

Steps:

  • Click Add Users.
  • Select Web application and Extranet zone.
  • To select the role, click the browse icon (open book image).
  • In the find text box, enter Agent.
  • Select role from list, click Add and then OK.
  • Tick the box to give the users full read permissions.

I have found that even though we told SharePoint to show exceptions, it does not show exceptions when using the “Policy for Web Application” function.
Test the forms authenticated login
The job is not complete without a login test. If the default site is at http://yourserver:80 then Extranet site is at http://yourserver:10080
Navigate to the Extranet site and login using the user name and password that was created in the “Create users and roles” section above. You may also test the default site just to be sure it remains accessible using Windows authentication.

Quick and Dirty User Profile

By using the existing user membership fields of the application services database, we can jump-start a few basic user profile fields. The more complete solution of using SharePoint user profiles and InfoPath will not be discussed here.

Using the same development machine website that was used to create the users and roles (above),

  • Click on Security.
  • Click on Manage users.
  • Find a user and click “Edit user”
  • In the description field, enter some user specific information (like an agent number).
  • Click Save

To use the user specific information in your WebPart code, try the following code snippet:
ASP.NET
MembershipUser user = Membership.GetUser();
_AgentNumberTextBox.Text = user.Comment;

This was really quick and really dirty. For example, if the same WebPart is accessed within the default Windows authentication site, the site will attempt to open the default membership profile database and will most likely fail. It will fail because no membership provider was defined in the web.config (it was only defined in the web.config of the extranet forms authentication site). Typically the default membership provider from the machine.config is used and the default configuration, in that case, points to a local SQL Express database file. A solution follows, but instead you may choose to aim for proper SharePoint user profile features.

Detect which Site

When the same WebParts appears in both the default Windows authentication site and the extranet forms authentication site, you may want to make some code conditional. The code illustrated above is a good example of what could go wrong with a common WebPart.

Here is an example of how to detect which site is current and conditionally run the code:

C#
SPSite site = SPContext.Current.Site;
if (site.IISAllowsAnonymous)
{
        //Currently running the Extranet site
        MembershipUser user = Membership.GetUser();
        _AgentNumberTextBox.Text = user.Comment;
}
else
{
        //Currently running the default Windows authenticated site
        …
}

The above detection code assumes the default site has “Allow anonymous” turned off and the Extranet site has “Allow anonymous” turned on.

Conclusion

Hopefully this article will save you hunting around for solutions as I did. At the end of the effort you will have a basic forms authenticated SharePoint site and nothing more. The next step forward depends very much on what problems you encounter. Maybe another article on WebPart trust level, Shared Service Providers or InfoPath will help.

History

25 Jul 2008 - Initial version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)