![]() |
Enterprise Systems »
SharePoint Server »
General
Advanced
License: The Code Project Open License (CPOL)
Guide to create forms authentication on SharePoint (1 of 2)By Johan FourieThe first of two articles about the steps I took to create forms based authentication on SharePoint . |
C#, Architect, Dev
|
||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
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.
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.
Use this wizard to create a database called AspNetSqlMembership on YOURDBSERVER.
re:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ aspnet_regsql.exe
Notes:
Use the “ASP.NET Configuration” feature of VS2008 to quickly create users.
Steps:
<connectionStrings>
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer"
connectionString="Server=YOURDBSERVER;
Integrated Security=SSPI;
Database=AspNetSqlMembership;"
providerName="System.Data.SqlClient"/>
</connectionStrings>
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 your existing site to create a new Extranet site.
re:
Central Administration > Application Management > Create or Extend Web Application
Steps:
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.
<configuration>
<SharePoint>
<SafeMode … CallStack="true" …
…
Also turn off custom errors.
<customErrors mode="Off" />
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
<configuration>
<connectionStrings>
<add name="AgentSiteConnectionString"
connectionString="Server=YOURSERVER;Integrated Security=SSPI;
Database=AspNetSqlMembership;"
providerName="System.Data.SqlClient" />
</connectionStrings>
…
<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.
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
<configuration>
<connectionStrings>
<add name="AgentSiteConnectionString"
connectionString="Server=YOURSERVER;Integrated Security=SSPI;
Database=AspNetSqlMembership;"
providerName="System.Data.SqlClient" />
</connectionStrings>
…
<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>
…
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:
<authentication mode="Forms">
<forms loginUrl="/_layouts/login.aspx" />
</authentication>
<identity impersonate="true" >
To <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.
An administrator can now associate the new role with the Extranet site.
re:
Central Administration > Application Management > Policy for Web Application
Steps:
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.
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),
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.
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:
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.
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.
25 Jul 2008 - Initial version.
| You must Sign In to use this message board. | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 24 Jul 2008 Editor: Sean Ewington |
Copyright 2008 by Johan Fourie Everything else Copyright © CodeProject, 1999-2009 Web20 | Advertise on the Code Project |