Tuesday, July 30, 2013

SharePoint 2007 and ADFS with "custom" SharePointClaimsMembershipProvider

As requirements for a customer project, we need to migrate a SharePoint 2007 (MOSS 2007) from ADAM Authentication to ADSF 2.0 Authentication.
MOSS is configured to use Form Based Authentication (FBA) using ootb LDAP Authentication Provider.

Now, in order to use ADFS to authenticate MOSS users what we need is to install and configure "Microsoft Federation Extensions For SharePoint 3.0".

The setup install an assembly in GAC that is Microsoft.IdentityModel.SharePoint12.dll.
An utility is also provided in order to configure a specific zone of our Sharepoint Web Application.

This utility change the web.config of Central Administration and the web.config of our Web Application, adding information about this new Authentication Provider.

The name attribute is configured as "SharePointClaimsMembershipProvider".
This is the interessed session:

 <membership defaultProvider="SharePointClaimsMembershipProvider">
      <providers>
        <add name="SharePointClaimsMembershipProvider" type="Microsoft.IdentityModel.SharePoint12.SharePointClaimsMembershipProvider, Microsoft.IdentityModel.SharePoint12, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </providers>
    </membership>


So the point: in our environment users where configured using a different name as Authentication Provider and we do not want to migrate every users defined in the SharePoint web application. Simply change name attribute of the autnetication provider in both web.config and in the specific session of Central Administration and ... voilĂ  ... Web App is broken.

The message is "Cannot Find Default Provider".

But my web.config is configured as follow:

 <membership defaultProvider="externalusers">
      <providers>
        <add name="externalusers" type="Microsoft.IdentityModel.SharePoint12.SharePointClaimsMembershipProvider, Microsoft.IdentityModel.SharePoint12, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </providers>
    </membership>


And for me the (only) provider is correctly defined.
So, where is the trick?

I've done rev-eng of the assembly and what I've found is that the Init Method of the class simply call the .base method of MembershipProvider base class using a constant.

This costant is "SharePointClaimsMembershipProvider". So this is the reason of the failure. The init method of the class ignore the name attribute we've defined in web.config and it use the above constant.

To be able to use our own membership provider name you need to change the init method of the Microsoft class to use the name that the .net framework use to inizialize the provider. So I've changed the method in this way.

  public override void Initialize(string name, NameValueCollection config)
  {
            //base.Initialize("SharePointClaimsMembershipProvider", config);
            base.Initialize(name, config);
  }

 
There's also another method you need to change. It's "FindUsersByEmail" that also use the constant "SharePointClaimsMembershipProvider".

I've recompiled everything using a different signature file and changing the assembly version.
Finally I was able to use "default" .net framework behaviour whit ADFS and MOSS 2007 ;) and this save me from migrate every users ACL in Sharepoint.

No comments: