www.geekybob.com

Just a short, simple blog for Bob to share his thoughts.

My SharePoint 2007 Custom Membership Provider Adventure

31 May 2011 • by Bob • SharePoint

Sometime last year I wanted to set up a SharePoint 2007 website for my family members to exchange information. That being said, I was using a custom membership provider, and I ran into a few issues while I was setting things up. I had kept detailed notes while I was configuring my server and troubleshooting the problems that I encountered, and with that in mind, I thought that I would share my experiences. ;-]


Getting Started

Specifying My Environment

My web server is only an older 32-bit Windows Server 2008 computer, so I couldn't install SharePoint 2010 (which is 64-bit only) and I had to install SharePoint 2007. Taking that into account, there were a few additional considerations that I had for my environment:

  • I wanted to use Forms-Based Authentication (FBA). Even though I run my own active directory domain, I avoid giving out physical accounts if I don't have to, so FBA seemed like a great idea.
  • I didn't want to use the built-in ASP.NET membership and roles provider. This is for two reasons:
    • I was already using the built-in ASP.NET membership provider on other websites, and I didn't feel like researching whether I should share the membership database between SharePoint and my other websites, or if I should set up unique membership databases.
    • If you've been reading my previous blogs and you think that I'd be content with using a built-in provider, then you haven't been paying attention. Usually I find myself wanting to do things the hard way, and other times I simply want to write code, but either way I decided to use the sample read-only XML membership and role providers that I documented in the following article:
  • I decided that I could use FBA over HTTP, and therefore I didn't worry about setting up SSL. (I run my own certificate server, so I could have issued myself a certificate and given the root CA certificate to everyone; but this wasn't necessary, so I didn't bother with it.)

Researching My Scenario

With my specific considerations in mind, I took a look at the following article to get started:

That being said, I did not use the following articles, even though they are related to my scenario and they looked interesting:


Creating the SharePoint Website

Here are the brief details on how I created my SharePoint website:

  1. I followed the steps in the following walkthrough in order to create and register the read-only XML membership and role providers with IIS 7:
  2. I created the following physical paths for my website:
    • Website root folder: C:\Inetpub\SharePointSite\wwwroot
    • Application data folder: C:\Inetpub\SharePointSite\wwwroot\App_Data
  3. I created the following user/role XML file for my website:
    • I created an XML file in the location: C:\Inetpub\SharePointSite\wwwroot\App_Data\MyUsers.xml
    • I added the following XML to the file:
      <Users>
         <User>
            <UserName>Alice</UserName>
            <Password>P@ssw0rd</Password>
            <EMail>alice@contoso.com</EMail>
            <Roles>Admins</Roles>
         </User>
         <User>
            <UserName>Bob</UserName>
            <Password>P@ssw0rd</Password>
            <EMail>bob@contoso.com</EMail>
            <Roles>Authors</Roles>
         </User>
      </Users>
  4. I opened the Internet Information Services (IIS) Manager and created a new website; I used the C:\Inetpub\SharePointSite\wwwroot folder for the home directory.
  5. I opened SharePoint 3.0 Central Administration to convert my website into a SharePoint 2007 site:
    1. I clicked the Application Management tab, then clicked Create or extend Web application, and then clicked Create a new Web application:
      • In my case I chose Use an existing IIS web site because I had already created the website that I wanted to use.
      • I chose Create new application pool, I used "Network Service" for the identification, and then I specified all of the requisite database information.
    2. When that completed, I clicked the Application Management tab, and then clicked Create site collection:
      • I specified all options, and I used a valid Active Directory account as the administrator for now.
    3. Once the site was created, I modified the web.config file for the website and the SharePoint Central Administration web.config file. (See the following notes for the details.) Note: The SharePoint Central Administration website needs to know the information about your membership provider in order to add administrators.
    4. After that, I clicked the Application Management tab, and then clicked Authentication Providers:
      • I verified that I was using the correct "Web Application" in the drop-down menu.
      • I clicked on the Default zone.
      • I set the Authentication Type to Forms.
      • I specified the appropriate Membership provider name and Role manager name.
    5. When that completed, I needed to restart IIS before continuing. (NOTE: I used "iisreset" from a command line.)
    6. After IIS had restarted, I clicked the Application Management tab, and then clicked Site collection administrators:
      • I added a user (like Alice or Bob) from the membership provider.

Web.Config Entries

There are a few additions that you have to make to your website's web.config file, as well as the SharePoint Central Administration web.config file for SharePoint 2007:

  • Here's the XML that you need to add to the <system.web> section of your website's web.config; in my example that file would be located at "C:\Inetpub\SharePointSite\wwwroot\web.config":
    <!-- added on 05/31/2011 -->
    <membership defaultProvider="ReadOnlyXmlMembershipProvider">
      <providers>
        <add name="ReadOnlyXmlMembershipProvider"
          type="ReadOnlyXmlMembershipProvider, ReadOnlyXmlMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=426f62526f636b73"
          description="Read-only XML membership provider"
          xmlFileName="~/App_Data/MyUsers.xml" />
      </providers>
    </membership>
    <roleManager enabled="true" defaultProvider="ReadOnlyXmlRoleProvider">
      <providers>
        <add name="ReadOnlyXmlRoleProvider"
          type="ReadOnlyXmlRoleProvider, ReadOnlyXmlRoleProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=426f62526f636b73"
          description="Read-only XML role provider"
          xmlFileName="~/App_Data/MyUsers.xml" />
      </providers>
    </roleManager>
    <!--/added on 05/31/2011 -->
  • Here's the XML that you need to add to the <system.web> section of your SharePoint Central Administration web.config file; on my server that file is located at "C:\inetpub\wwwroot\wss\VirtualDirectories\6087\web.config":
    <!-- added on 05/31/2011 -->
    <membership defaultProvider="ReadOnlyXmlMembershipProvider">
      <providers>
        <add name="ReadOnlyXmlMembershipProvider"
          type="ReadOnlyXmlMembershipProvider, ReadOnlyXmlMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=426f62526f636b73"
          description="Read-only XML membership provider"
          xmlFileName="~/App_Data/MyUsers.xml" />
      </providers>
    </membership>
    <!--/added on 05/31/2011 -->

IMPORTANT!!!

SharePoint Central Administration needs to be able to find the MyUsers.xml file, so I created an App_Data folder under physical path of the SharePoint Central Administration website, and I added a symbolic link in that folder that pointed to the physical MyUsers.xml file. Here's how I did that:

  1. I opened a command prompt.
  2. I changed directory to the path where my SharePoint global web.config file was located; for example:
    cd C:\inetpub\wwwroot\wss\VirtualDirectories\6087
  3. I created a symbolic link to the physical path of the XML file; for example:
    mklink MyUsers.xml C:\Inetpub\SharePointSite\wwwroot\App_Data\MyUsers.xml
  4. I closed the command prompt.

Note: I could have copied the XML file, but I preferred to use the symbolic link instead of having to manage two copies of the file.

Optional People Picker Settings

If you were installing a membership provider that can perform lookups, you could add an additional entry to your SharePoint Central Administration web.config file:

<PeoplePickerWildcards>
  <clear />
  <add key="AspNetSqlMembershipProvider" value="%" />
  <!-- added on 05/31/2011 -->
  <add key="ReadOnlyXmlMembershipProvider" value="%" />
  <!--/added on 05/31/2011 -->
</PeoplePickerWildcards>

Problems that I Encountered

Okay - I admit that I everything that I did so far was probably making things harder that they needed to be, but I love a good challenge. ;-]

That being said, I ran into some problems that I thought would be worth mentioning, just in case someone else ran into them.

HTTP 403 Errors

When browsing to my SharePoint website, I received several HTTP 403 errors. I used Process Monitor to troubleshoot the problem, and I discovered that IUSR could not access the "bin" folder in my website. (I'm still not quite sure why it was trying.) To resolve these errors, I used the following steps:

  1. I opened a command prompt.
  2. I changed directory to the SharePoint website's path; for example:
    cd C:\Inetpub\SharePointSite\wwwroot
  3. I changed permissions for the "bin" folder; for example:
    icacls bin /grant IIS_IUSRS:r
  4. I closed the command prompt.

In my situation the problem was for IUSR, but if you are using a different anonymous identity or your application pool is running as a unique identity then it might be a different user. In any case, Process Monitor will let you know who needs permissions.

Later I discovered the following blog post by John Powell:

http://blogs.msdn.com/b/johnwpowell/archive/2008/05/23/sharepoint-intermittent-403-forbidden-errors.aspx

In that blog, John suggests adding the following permissions for the "bin" folder:

icacls bin /grant users:r

I'm not sure if that's necessary, but it's worth pointing out.

HTTP 404.8 Errors

When browsing to my SharePoint website, I received several HTTP 404.8 errors. Those errors mean that the built-in IIS 7 Request Filtering feature was blocking something, so I did the following:

  • I opened my website's web.config file; on my server that file was located at "C:\Inetpub\SharePointSite\wwwroot\web.config":
  • I added the following XML before the closing </configuration> tag:
    <system.webServer>
      <!-- added on 05/31/2011 -->
      <security>
        <requestFiltering>
          <hiddenSegments>
           <clear />
           <add segment="web.config" />
           <add segment="bin" />
           <add segment="App_code" />
           <add segment="App_GlobalResources" />
           <add segment="App_LocalResources" />
           <add segment="App_WebReferences" />
           <add segment="App_Data" />
           <add segment="App_Browsers" />       
          </hiddenSegments>
        </requestFiltering>
      </security>
    <!--/added on 05/31/2011 -->
    </system.webServer>
  • I saved and closed the web.config file.

Note: This removes all of the hidden segments from the global IIS 7 Request Filtering settings, which may be overkill. I have a lot of custom global request filtering settings, and I didn't want to go through each individual setting to see which setting was blocking files that I needed, so I used settings for my website that cleared the inherited request filtering settings and added the default settings.

Annoying Message: "The Web site wants to run the following add-on: 'Name ActiveX Control'"

When browsing to my SharePoint website, the information bar in Internet Explorer kept prompting me with the following message:

The Web site wants to run the following add-on: 'Name ActiveX Control' from 'Microsoft Corporation'. If you trust the Web site and the add-on and want to allow it to run, click here...

This message was highly frustrating, so I did some digging around the Internet and discovered that I could hack the INIT.JS file for SharePoint to suppress this message. Here's how I did that:

  • I opened my server's INIT.JS file; on my server that file was located at "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\1033\INIT.JS".
  • I located the ProcessImn() and ProcessImnMarkers() functions, and I remarked out the contents. Here's what this looked like when I was done:
    function ProcessImn()
    {
    // if (EnsureIMNControl() && IMNControlObj.PresenceEnabled)
    // {
    // imnElems=document.getElementsByName("imnmark");
    // imnElemsCount=imnElems.length;
    // ProcessImnMarkers();
    // }
    }
    function ProcessImnMarkers()
    {
    // for (i=0;i<imnMarkerBatchSize;++i)
    // {
    // if (imnCount==imnElemsCount)
    // return;
    // IMNRC(imnElems[imnCount].sip,imnElems[imnCount]);
    // imnCount++;
    // }
    // setTimeout("ProcessImnMarkers()",imnMarkerBatchDelay);
    }
  • I saved and closed the INIT.JS file.

I should note that this solution is unsupported; and a few months I hacked my INIT.JS file, Microsoft published the following Knowledge Base article with a couple of different methods:

KB 931509: Message in the Information bar in Internet Explorer 7 when you browse to a Windows SharePoint Services 3.0 site or to a SharePoint Server 2007 site: "The Web site wants to run the following add-on: 'Name ActiveX Control'"

That being said, I like my solution better. ;-]


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

Tag Cloud

11th-ACR 511th-MI-Company Access Add-ins ADSI Animals Antivaxxers AppCmd Apple Arizona Army Art ASP ASP.NET Atheism Authentication Bass Batch Files Bicycling BlogEngine.NET Blogging BSOD Business C# Campaigning Capitalism Cats Certificates Childhood Christianity Christmas Classic ASP Communism Computers Conspiracy Content Cookies COVID19 CPP Database Dell DIY Dogs Domain Administration Easter Ecology Education Effects Entertainment Environment Errors Essential-Tremor Exercise Expression Web Extensibility Facebook Family Fashion Feedback FFmpeg Filters Food FPSE Friends FrontPage FTP FTP Clients FTPS Gaming Germany GPO Grandparenting Guitar Halloween Hardware Hawaii Health History Hobbies Hotkeys HP HTML HTMLA HTTP HTTPS Humor IE IIS IIS 5 IIS 6 IIS 7 IIS 7.5 IIS 8 IIS 8.5 IIS Express Internet JavaScript Keystrokes Kickstarter Kids Languages LDAP Linguistics Log Files Log Parser LogParser Macros Marriage Math Media Membership Microsoft MIDI Military Miscellaneous Mods Movies Music Nature Nostalgia Office OneDrive Opinion Outlook PaintShop Parenthood Parody Peace Performance Philosophy Photography PHP Poetry Politics Ponderings PowerShell Programming Projects Proxy Puns PWS Random Thoughts Rants Religion Reviews RSCA Rush Russia Satire Science Scripting SDK Seattle Security SEO SharePoint Sibelius SkyDrive Socialism Space Sports Squirrels Squirrels, Humor SSI SSL Star Trek STEM Support Surface TechEd Technology Television Templates Thanksgiving Themes Transcription Travel Troubleshooting Tucson Upgrades URL URL Rewrite User Isolation VBA VBScript Video Visio Visual Basic Visual Studio VLC W3C Web API WebDAV WebMatrix Weight Loss WinCache Window Media Center Windows Windows 10 Windows Cache Extension Windows Phone 7 WMI Word Work Writing WSH XML XSL Zune