I know, Sharepoint 2007 is pretty old. However, this week a client wanted FBA for his WSS 3 environment, so no problemo for the Sharepoint pro. I haven’t done a FBA config for Sharepoint 2007 before, so I did a bit of googling and couldn’t find a very explaining article that covers the whole configuration. There were a few handy sites, including the MSDN, which helped me out getting what I needed.

Further on it will be explained in detail, but here is a summary already:

  • ASP.NET membership database (aspnet_regsql.exe)
  • Extended web application with zone internet
  • Edit web.config of the default web application and the extended web application
  • Install http://fba.codeplex.com/ wsp

Install ASP.NET membership database

Run the tool aspnet_regsql.exe at C:WindowsMicrosoft.NETFrameworkv2.0.50727

Choose the option to configure SQL Server for application services.

Choose the name of the database server in the server field. Choose Windows authentication and type a database name in the Database dropdown field. In this case we creat a database with the name fbadb.

Click next and Finish to complete the creation of the membership database.

Set the right SQL permissions

Because we wan´t to use integrated security with the connection we need to give the application pool identity the appropriate permissions on the membership database. First of all we need to know what the application pool identity is. For that you can go to the IIS Manager and select the Sharepoint site.

Click Advanced Settings… and note the Application Pool

Then click on Application Pools and select the noted application pool

Click Advanced Settings … and note the identity, in our case this is the Network Service

Now, go to SQL management studio and give that user the db_owner permissions on the FBA database we just created.

Extended web application with zone internet

Open Central Administration. Go to Create or extend web application in Application Management and click Extend an existing web application. In web application select the web application you wish to create FBA for.

However we are extending a web application, we need to create a new IIS web site so leave that option on.
I want to  create a subsite for the FBA authentication, so I did set the port back to port 80 and set the host header to extranet.mydomain.com

Allow anonymous authentication and here you can also choose to use SSL or not. I choose not to use SSL. The last thing to do is to set the zone to Internet.

You can go to the url of the extended web application to check if the configuration works.

Last thing to do is to enable FBA on the extended web application. Go back to Central Administration and then click Authentication providers under Application Security. Then click on the Internet zone.

In this screen select the Forms authentication type. Two new fields appear: Membership provider name and Role manager name. This are the names of the membership and role provider we are going to configure in the next step. I’m using FBA for Membership provider name and FBARole for the role manager name.

Click Save and all central admin settings are set.

Edit web.config of the default web application and the extended web application

Next thing to do is to add a few items to the web.config of the web application and the extended web application:

  • Peoplepicker wilcard for FBA
  • Connectionstring for the FBA Database
  • Membership provider for FBA Users
  • Role manager for FBA Roles

Go to the web.config of the web application (not the extended web application) and search for the </sharepoint> closing tag and the <system.web> starting tag; they should be next to eachother.

Just above </SharePoint> you find the following piece of code:

<PeoplePickerWildcards>      
  <clear />      
  <add key="AspNetSqlMembershipProvider" value="%" />      
</PeoplePickerWildcards>
replace this with the next code:
<PeoplePickerWildcards>      
  <clear />      
  <add key="AspNetSqlMembershipProvider" value="%" />      
  <add key="FBA" value="%" />    
</PeoplePickerWildcards>

Now add a new ConnectionString section between the </sharepoint> and <system.web> tags:

<connectionStrings>    
  <add name="fbaSQL" connectionString="server=localhost;database=fbadb;Trusted_Connection=true" />  
</connectionStrings>

Because I run the database and Sharepoint on the same server I’m using localhost. If you are using a different database server you need to replace localhost with the database server name or ip here, pretty obvious.

Last thing to do is to add a membership and role section in the <system.web> tag. Add the following piece of code just below <system.web> and above <securityPolicy>:

<membership defaultProvider="FBA">      
  <providers>        
    <add connectionStringName="fbaSQL" applicationName="/" name="FBA" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"            
      enablePasswordRetrieval="false"            
      enablePasswordReset="true"            
      requiresQuestionAndAnswer="false"            
      requiresUniqueEmail="true"            
      minRequiredPasswordLength="5"            
      minRequiredNonalphanumericCharacters="0"            
      passwordFormat="Hashed" />      
  </providers>    
</membership>    
<roleManager enabled="true" defaultProvider="FBARole">      
  <providers>        
    <add connectionStringName="fbaSQL" applicationName="/" name="FBARole" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>      
  </providers>    
</roleManager>

This web.config is done. Now do the same for the web.config of the extended web application.

Install http://fba.codeplex.com/ wsp

Download FBAManagement.wsp and Deploy.cmd from http://fba.codeplex.com/releases/view/2986 and save both files into the same folder. We need to edit some values in the Deploy.cmd so once downloaded go to the folder and rightclick Deploy.cmd and click edit. Now replace both http://aspnet with http://<yoursharepointsite>. Also remove the bin from “stsadm -o addsolution -filename binFBAManagement.wsp” so it reads only “stsadm -o addsolution -filename FBAManagement.wsp”. The code should look like this:

@echo Deploying FBAManagement solution

@set PATH=C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12BIN;%PATH%

stsadm -o deactivatefeature -name FBAUserRoleManagement -url http://mysharepoint -force
stsadm -o deactivatefeature -name FBAConfigurationManagement -force

stsadm -o retractsolution -name FBAManagement.wsp -immediate
stsadm -o execadmsvcjobs
stsadm -o deletesolution -name FBAManagement.wsp -override
stsadm -o execadmsvcjobs

stsadm -o addsolution -filename FBAManagement.wsp
stsadm -o execadmsvcjobs

stsadm -o deploysolution -name FBAManagement.wsp -immediate -allowgacdeployment
stsadm -o execadmsvcjobs

stsadm -o activatefeature -name FBAConfigurationManagement
stsadm -o activatefeature -name FBAUserRoleManagement -url http://mysharepoint
stsadm -o execadmsvcjobs

Save the file and execute it as administrator. Don’t be scared with the file not found and solution not found messages for the first few lines, because thats entirely normal.

Result

All configuration is done. Go to the site settings of the sitecollection. Under site collection administration you find two new links. With Manage FBA Users you can add and edit users and with Manage FBA Roles you can add and edit roles, which is pretty straightforward.

To test FBA you can add a user and give the user some permissions by adding it to the Team Site Members group. Now, login with the user on the extended web application and see the result.

I have done a few years of sharepoint developing now. When I began to write small webparts in Sharepoint I was very enthusiastic about the features of the Sharepoint framework and thought it was as easy and solid as writing ASP.NET. Now I know better, developing Sharepoint masterpages, webparts, workflows, etc. is not all beer and skitties. Also when you haven’t encountered any troubles yet, you will get to it! So don’t waste your effort on developing the wrong way.

Here are some points of what I consider “Sharepoint 2007 developing and designing: Best practices”

Developing

  • Sharepoint Designer is crap. It´s instable and unfinished. So, try to avoid it where possible. Try to use Visual Studio instead.
  • Use Microsofts Visual Studio extensions for WSS. Always use the latest version: CTP, Beta or RC? It all did work for me, so just use it. Here’s a link to the latest version: http://www.microsoft.com/downloads/details.aspx?familyid=FB9D4B85-DA2A-432E-91FB-D505199C49F6&displaylang=en
  • Always use embedded resources, never copy your images, css or javascripts to a folder in the 12 hive. An article on how to use embedded resources can be found here: http://aspalliance.com/726
  • Important! Before developing get you’re Functional Requirements straightened out. It is very important to know if you are going to create an application that is going to be updated (frequently) AND/OR needs to work in other environments, for example an ASP.NET environment AND/OR if it needs to be compatible with other/future versions of sharepoint. If it does, and the most cases will be, then mind the following points
    • Try to use the Sharepoint controls in the Microsoft.SharePoint.WebControls namespace as less as possible. Some controls contain some bugs and off course this way you can easily use the same application in an ASP.NET webpage or implement it in another version of Sharepoint.
    • Create a tiered application. Create for every tier a new project. Create a SharepointData project which handles all data between your project and sharepoint, like users, groups, properties, lists, libraries
    • Try to avoid the use of the IWebEditable interface and the EditorPart class. Handle configurations in a second webpart where only an admin can touch it.

Designing (Master pages)

  • Again. SharePoint Designer is crap, but with designing a master page we cannot evade the piece of beta-software Microsoft has shipped with SharePoint. So, good luck with the frustrations.
  • A disadvantage of Sharepoint is that you cannot deploy a masterpage centralized, you have to do a copy-paste job to create the same look on all sites. Fortunately I have a feature for globally deploying masterpages. In a few steps you can build your own feature, it’s very easy. Here is the article: http://www.dontpapanic.com/blog/?p=36
  • WARNING! NEVER EVER overwrite the default masterpage located at 12TEMPLATEGLOBAL but use it only to copy, it would be wise to make a backup of it.
  • I discourage the use of a minimalistic masterpage.  Use the default sharepoint masterpage located at <%System Drive%>Program FilesCommon FilesMicrosoft SharedWeb Server Extensions12TEMPLATEGLOBAL as you’re base masterpage. Generally implementing a new design will take less effort when tweaking the default masterpage, than creating a new one based on a minimalistic base masterpage.

These are the important points that have been in my head for a while, finally they got stored in HTML and are they readable for others. Did I miss something or do you have any tips yourself? I ‘ll be glad to know.

What I wanted to do is adding a delete button to each item in the listview to delete a record directly from the overview. Sharepoint has an edit button that can be inserted by adding the “Edit” column in the view editor. It’s a shame that Sharepoint doesn’t have a similar option for deleting. This doesn’t mean it is impossible, it’s just not that easy, here you go:

<IsVisible>true</IsVisible>

Open SPD(Sharepoint Designer) and go to the list you want to add the button to and open the AllItems.aspx

duplicate the ListViewWebPart by copying the following code and pasting it directly after itself.

<WebPartPages:ListViewWebPart runat="server" __MarkupType="xmlmarkup" WebPart="true" __WebPartId="{28B30FD4-BA90-4FFE-8EA6-2608237AF16B}" >
...
...
</WebPartPages:ListViewWebPart>
find the following line in the second web part and change
<IsVisible>true</IsVisible>

to

<IsVisible>false</IsVisible>

Be sure that the first listform is now visible when you go to the list with your browser.

In SPD rightclick the first listview and click “Convert to XSLT Data View”. You can now edit every column, value and formula. Create a new column where you want the delete button to be. In my case I want it next to the edit button so I rightclick that column and insert a column to the right.

In the newly created column you can change the header to “Delete” or “Remove” or whatever you want.

Now we need to locate the empty cell in code view. Assuming you have split view we’re going to select only the first two cells (not the header) of the newly created column, you see the code view jump.  Now locate the empty

<TD Class="{$<SomeId>}"></TD>

or

<TD Class="{$<SomeId>}">

 

<xsl:text xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" ddwrt:nbsp-preserve="yes" disable-output-escaping="yes">&amp;nbsp;</xsl:text>
</TD>

in your selected code and replace it with

<TD Class="{$<SomeId>}">

<xsl:choose>

<xsl:when test="ddwrt:IfHasRights(4)">

<a href="javascript: {ddwrt:GenFireServerEvent(concat('__cancel;__delete={ID=',@ID,'};__commit'))}"><img border="0" alt="Edit" src="/_layouts/images/delete.gif" /></a>

</xsl:when>

<xsl:otherwise>

<xsl:text xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" ddwrt:nbsp-preserve="yes" disable-output-escaping="yes">&amp;nbsp;</xsl:text>

</xsl:otherwise>

</xsl:choose>
</TD>

Now we are done, save and enjoy deleting! =)

Update

For them who want to have a conformation box before deleting just insert this code instead of the above:

<TD>
<xsl:choose>
<xsl:when test="ddwrt:IfHasRights(4)">
<a href="javascript: if(confirm('Are you sure you want to delete?')){ddwrt:GenFireServerEvent(concat('__cancel;__delete={ID=',@ID,'};__commit'))}"><img border="0" alt="Edit" src="/_layouts/images/delete.gif" /></a>
</xsl:when>
<xsl:otherwise>
<xsl:text xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" ddwrt:nbsp-preserve="yes" disable-output-escaping="yes">&amp;nbsp;</xsl:text>
</xsl:otherwise>
</xsl:choose>
</TD>