Wednesday 20 June 2012

HOW TO:Forms Based Authentication (FBA) on SharePoint 2010

** Note: This FBA configuration method is based upon the pre-release version of SharePoint 2010 and may change in the final release **

The following article details FBA configuration on a SharePoint 2010 site.

Setup your SharePoint 2010 site

  1. In Central Admin, create a new site. By default, this will use Windows Authentication. Since we haven’t setup FBA yet, we need to setup the Web Application first as a Windows site.
  2. Create the Web Application
  3. Create a default Site Collection, and make a windows user (below we’ve used the Administrator account) a Site Administrator.

Setup your User Database

  1. Setup the ASP.NET Membership Database. Note: You can use custom membership stores, DotNetNuke, even Live! credentials. But the .NET membership database is very simple to setup. This requires the SQL Server database. You can use the integrated version that is supplied with SharePoint, Express or a fully featured SQL Server (Standard or Enterprise) Edition.
  2. Find the setup file aspnet_regsql.exe located at either of the following locations depending upon your OS:
    %windir%\Microsoft.NET\Framework\v2.0.5027
    %windir%\Microsoft.NET\Framework64\v2.0.5027
  3. When the ASP.NET SQL Server Setup Wizard appears, select “Configure SQL Server for application services”, then click Next
  4. Enter the SQL Server and Database name.
    sqldb
  5. Above, I have named the database FBADB
  6. Click Next and Finish

Provide Access to the Membership Database

As an administrator, you’ll be able to add and modify user accounts. But from the SharePoint runtime, we’ll have to provide access to the membership store. This can be done in two ways. If using SSPI (Integrated Security) for the connectionstring from SharePoint, you’ll need to determine the Service Account that runs the Application Pool. Then you’ll provide access to this windows (or service) account in SQL Server to the FBADB database. Or, if you don’t want to use SSPI, or don’t want to take the time to figure out the startup service account for SharePoint you can simply create a login to the FBADB database. Following are steps for the second approach.
  1. Open SQL Server Management Studio (SSMS 2008) and select Security , then Logins
  2. Right Click Logins and Select “New Login”
  3. Create a SQL Server account. Below, we’d created the account FBAService with password pw
    sqluser2
  4. Select “User Mapping”
  5. Mark the checkbox next to FBADB, and select the row.
  6. In “Database role membership”, make the user a dbo_owner.rolemember
  7. Click OK to save the new user.

Setup IIS 7.0 Defaults

  1. Open up Internet Information Services Manager 
  2. Select the Web Server, then double click Connection Strings
    Cstring
  3. Click Add..
  4. Enter the Server (.), Database (FBADB) and the Credentials for the user FBAService (by clicking the Set button). If you want to use SSPI, simpy select “Use Windows Integrated Security” instead.
    cstring2
  5. Click OK to save
  6. Click to Select the Server from the Connections pane again, and double click Providers.
  7. On the Feature dropdown, select .NET Users. Your machine may take a while to respond while the configuration is read.
  8. On the Actions menu, click Add..
  9. On the Add Provider form, select SqlMembershipProvider as the Type
  10. Provide a name: FBA.
  11. Drop down ConnectionStringName and select FBADB
  12. Set any other parameters you’d like. I set some Password related options for user interaction later.
    provider
  13. Click OK to save
  14. From the Feature dropdown, select .NET Roles, then click Add..
  15. Provide a name: FBARole, and select TypeSqlRoleProvider
  16. Select the ConnectionStringName: FBADB
    roleprovider
  17. Click OK to save the .NET role.

Setup the FBA Zone in SharePoint 2010

  1.  Browse to SharePoint 4.0 Central Administration, Select Security
    centraladmin
  2. In Application Security, select Specify Authentication Providers
    specificauthent
  3. Select the Web Application.
  4. Click the Default Zone.
    defaultzone
  5. Ensure the Web Application is the correct one on the next page!
  6. Change Authentication Type to Forms
  7. Check Enable Anonymous (* note that this does not immediately enable Anonymous access; it merely makes the option available on the front-end web application *
    zone1
    zone2
  1. Click Save.
  2. When the process is finished, the membership provider should now display FBA.
What SharePoint has done behind the scenes is make the necessary changes to the IIS website to support Forms based authentication. But we still have a little problem. If we browse to the site right now, we won’t be prompted for Windows credentials anymore. Not only do we NOT have a user in the .NET membership database, but we have no FBA based administrators. Let’s tackle that next.

IIS 7.0 Web Site Configuration for SharePoint 2010 FBA

  1. In IIS Manager, select the SharePoint site. In this example, we used the default site (80).
  2. Double click the .NET Users icon
  3. Click Set Default Provider from the actions pane on the left and select FBA
    dftuser
  4. Click OK to save.
  5. While we’re here, let’s add our first user. This will be used as an administrative account on the FBA site. Click Add..
    newuser
  6. Select a User, Email and Password. Depending upon parameters you defined earlier you may be prompted with challenge/response questions.
    ** The password may require some strength by default. If you receive an error message that states the “password is invalid”, simply add a number or non-alpha character.
  7. Next, select the SharePoint Central Administation v4 web site from the connections menu in IIS.
  8. Click .Net Users, then in the Actions menu select “Set Default Provider” and set that to FBA.

Set the User as Site Administrator on the SharePoint 2010 Web Site

  1. In SharePoint Central Admin v4, go to Application Management
  2. In the Site Collections section, select “Change Site Collection Administrators
    siteadmins
  3. On the next page, select the Site Collection we’ve been using.
  4. You’ll note that the primary site collection administrator has a little red squiggly. Why? We don’t have Windows Authentication enabled for this site and therefore no way to resolve. Delete the Administator account.
  5. In the field type the user created above (we used fbaadmin), then click the Check Names button. You should see a black underline noting that the name was resolved.
    fbaadmin

Test the site

  1. In a Web Browser, when you access the site http://localhost (if that’s what you used), you’ll be presented with the SharePoint login screen, not a Windows login pop-up. (Wow, and you thought SharePoint 2007 had a spartan login screen. Get a load of this !)
    login
  2. Login with the fbaadmin credentials and you should be able to access the site.
    homepage2

Add the reference to the user friendly people picker

You know the picker…so you can easily find those needles in the haystack. For that to work in Central Admin and this site against your .NET membership database, you need to add a reference to the provider.
  1. In IIS Manager, browse to the Central Admin web application. Explore the folder and find the web.config file. Open in Notepad.
  2. Find the node and use the following:

Custom Form Base Login Web Part With Sharepoint 2010


image
Surely, it does not look pretty at all. So, you might want to change this default login page. In order to do this, first let us create an empty SharePoint project in Visual Studio 2010. After that, add an application page by right click-selecting “Add New Item” and you will get like the following window in Solution Explorer:
image
Notice that, when you add any application page to your project, Visual Studio automatically creates aLayouts folder. To keep things simple enough for your understanding, you may keep your application page under a folder where you might name it as same as your project like the figure above.
Now, add a reference for Microsoft.SharePoint.IdentityModel in your project. Open the application page, and add an assembly for that on the top of your application page Beofre the Page tag, you should have the following section in your application page:
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Assembly Name="Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.WebControls" %>
<%@ Register Tagprefix="SharePoint"
    Namespace="Microsoft.SharePoint.WebControls"
    Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI"
    Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
Now look ContentPlaceHolderID="PlaceHolderMain" and add a literal control and Login Control like the following:
<SharePoint:EncodedLiteral runat="server"
        EncodeMethod="HtmlEncode" ID="ClaimsFormsPageMessage"
        Visible="false" />
    <asp:Login ID="signInControl"FailureText="<%$Resources:wss,login_pageFailureText%>"
        runat="server" Width="100%" DisplayRememberMe="true"BackColor="LightCyan" BorderColor="DarkGreen" ForeColor="DarkBlue"InstructionText="Use KFUPM Internet Account to Login"InstructionTextStyle-ForeColor="DarkGreen" InstructionTextStyle-Font-Size="Small" />
Now, you can obviously customize according to your needs here. That’s it and our custom page is ready to use. So, save and deploy the project. After that, go to central administration->Application Management->Manage Web Application: select your web application for which you have enabled Form based authentication and click on Authentication Providers. Click on Default where a window will pop up and scroll down where you will see a section Sign In Page URL; select Custom Sign In Page and the path will be as the following format:
~/_layouts/ [Project name] / [Application Page Name].aspx
The following is the screenshot for my project:
image
Save it and go to your site collection/site login page which is using this FBA web app. When you will click on Sign In, you should get a page like the following one:
image
Custom Web Part  for signing in Form Based (Claims Based) Web applications:
You have seen until now that how can you create a custom login page for your FBA web application. Now, to improve the functionality like most of the public facing websites, you might want to put this login panel on the home page. Let us now discuss about creating a custom web part which will leverage us this option from home page where you can just add that webpart anywhere you like. So, let us get started.
Open Visual Studio 2010 and create an Empty SharePoint Project. To achieve our goal, we can add a normal web part or a visual web part to our project (Depending on the privilege of having the access to deploy the solution as Farm or Sandboxed). For this instance, I have chosen Farm based solution. So, I have added a Visual Web Part in my project (which is not possible in sandboxed solutions).  [In your case, if you do not have sufficient privilege, you can add a normal webpart and create the UI inside theCreateChildControls method of your webpart.]
Now, add the following references to your project:
Microsoft.IdentityModel
Microsoft.IdentityModel.WindowsToeknService
Microsoft.SharePoint.IdentityModel
For visual web part, add the Assembly name inside the .ascx page.
<%@ Assembly Name="Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
Now, add a login control to this ascx page like below and customize it according to your needs:
<asp:Login runat="server" ID="FBALogin" BackColor="#F7F6F3"
    BorderColor="#E6E2D8" BorderPadding="4" BorderStyle="Solid"BorderWidth="1px"
    Font-Names="Verdana" Font-Size="0.8em" ForeColor="#333333"Height="201px"
    onauthenticate="FBALogin_Authenticate" Width="390px">
    <InstructionTextStyle Font-Italic="True" ForeColor="Black" />
    <LoginButtonStyle BackColor="#FFFBFF" BorderColor="#CCCCCC"BorderStyle="Solid"
        BorderWidth="1px" Font-Names="Verdana" Font-Size="0.8em"ForeColor="#284775" />
    <TextBoxStyle Font-Size="0.8em" Width="100px" />
    <TitleTextStyle BackColor="#5D7B9D" Font-Bold="True" Font-Size="0.9em"
        ForeColor="White" />
</asp:Login>
Notice that, I have added an event handler here FBALogin_Authenticate which will perform the authentication (see the code below)
protected void FBALogin_Authenticate(object sender, AuthenticateEventArgs e)
        {
            Uri webUri = new Uri(SPContext.Current.Web.Url); //Getting the current context of URL
            string membershipProvider = "admembers"//Set the FBA authentication provider
            string roleProvider = "";
            e.Authenticated = SPClaimsUtility.AuthenticateFormsUser(
new Uri(SPContext.Current.Web.Url),
FBALogin.UserName,
FBALogin.Password);
            if (!e.Authenticated) return;
            SecurityToken secTk = SPSecurityContext.SecurityTokenForFormsAuthentication(webUri, membershipProvider, roleProvider, FBALogin.UserName, FBALogin.Password);
      
            if (secTk == null)
            {
                e.Authenticated = false;
                return;
            }
            else
            {
                SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;
                fam.SetPrincipalAndWriteSessionToken(secTk);
                e.Authenticated = true;
                SPUtility.Redirect(SPContext.Current.Web.Url, SPRedirectFlags.Trusted, this.Context);
            }
        }
Adding a Link for Windows Authentication on the Custom Login Web Part:
What if you want to add a link for windows authentication as well if your web application uses both form based and windows based authentication. For this, I have added a link for windows authentication on the web part.
Here below is the OnLoad event for the web part:
protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            EnsureChildControls();
            SPControlMode formMode = SPContext.Current.FormContext.FormMode;
            string returnUrl = "/";
            if (string.IsNullOrEmpty(
                this.Context.Request.QueryString["ReturnUrl"]) == false)
            {
                returnUrl = this.Context.Request.QueryString["ReturnUrl"];
            }
            winLoginLink.NavigateUrl =
                "/_windows/default.aspx?ReturnUrl="
                + returnUrl;
            if (formMode == SPControlMode.Edit || formMode == SPControlMode.New || this.Page.User.Identity.IsAuthenticated == true)
            {
                DisableLoginForm();
           
            }
        }
In this event, at first, I am checking the mode of the page whether it is new, edit or Logged in mode. We can get the URL for the validated URL from a query string called “ReturnUrl”.  Later on, I am setting the navigation URL link for the windows authentication and based on the page mode, hiding the login form which will hide the web part if the current page is in Edit, New or Logged In mode.
private void DisableLoginForm()
{
    this.EnsureChildControls();
    this.FBALogin.Enabled = false;

    this.FBALogin.VisibleWhenLoggedIn = false;
    DisableLoginValidator(this.FBALogin, "UserNameRequired");
    DisableLoginValidator(this.FBALogin, "PasswordRequired");
    winLoginLink.Visible = false;
}
Above code will hide our web part based on the context mode of the page. I will also need to disable the login validator which is provided below:
private static void DisableLoginValidator(
            Login loginControl,
            string validatorID)
        {
            Debug.Assert(loginControl != null);
            Debug.Assert(string.IsNullOrEmpty(validatorID) == false);
            RequiredFieldValidator validator = loginControl.FindControl(
                validatorID) as RequiredFieldValidator;
            if (validator != null)
            {
                validator.Enabled = false;
            }
        }
Now, we are ready to go. Deploy it on your target site or site collection where you will use this web part. After adding the web part on the page, it will appear as following screenshot:
image