How to Create – Sitecore Custom Membership Provider

Glad to be back to blogging again. I am working for a client where they have a home grown authentication and authorization system. They are going to deploy Sitecore hosted application and they want to integrate their Security System with Sitecore. No surprise. Who wants to replace a perfectly working system? Especially, when the same Security System is used by several other applications. So, I started looking into Sitecore documents and it is not difficult to find that, I have to create an ASP.NET Membership Provider to access my client’s Security System. The problem is that the information are scattered. In this blog, I am going to try to put together everything in one place that I learned and that worked for me, to make your life easy, if you are looking for this information and ended up here. Also, at the end of the blog, there will be references to the documents I used. You should read those documents for writing fully functional Membership Provider, because the one I am creating here is read only and purpose is to get you started.

Let’s start with some basic things. Sitecore uses ASP.NET Membership Provider for Authentication and Authorization of users and roles. But, as most of the other providers in Sitecore the architecture is extensible, so that, we can extend Sitecore to talk to Custom Membership Providers. Below is the Configuration for Membership Provider out of the box.

    <membership defaultProvider="sitecore" hashAlgorithmType="SHA1">
      <providers>
        <clear />
        <add name="sitecore" type="Sitecore.Security.SitecoreMembershipProvider, Sitecore.Kernel" realProviderName="sql" providerWildcard="%" raiseEvents="true" />
        <add name="sql" type="System.Web.Security.SqlMembershipProvider" connectionStringName="core" applicationName="sitecore" minRequiredPasswordLength="1" minRequiredNonalphanumericCharacters="0" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="256" />
        <add name="switcher" type="Sitecore.Security.SwitchingMembershipProvider, Sitecore.Kernel" applicationName="sitecore" mappings="switchingProviders/membership" />
      </providers>
    </membership>

There are three membership providers in the configuration. Our Custom Membership Provider needs to be added there as the above providers are added. The defaultProvider is “sitecore”. That gets called when initially. But, if you open up Sitecore.Security.SitecoreMembershipProvider class in reflector, you can see that, it is redirecting calls to RealProvider. Like below.

    public override MembershipUser GetUser(string username, bool userIsOnline)
    {
      return this.Wrap(Factory.GetRetryer().Execute<MembershipUser>((Func<MembershipUser>) (() => this.RealProvider.GetUser(username, userIsOnline))));
    }

In the Membership configuration above, the realProviderName=”sql” and that’s the provider gets called for Sitecore security. So if we add our Membership Provider and assign our provider to the realProviderName, Sitecore should call our provider. That’s good, but wait, there is more than that. Sitecore can Support more than one provider if you want to support more than one domain. That’s where the switcher comes into picture. If you see that last Membership Provider in the above membership configuration, it’s called switcher. It tells Sitecore to use specific Membership Provider via mappings attribute in the configuration. If you follow the mappings path (showed below), you can see how providers are used for domains. Well, in out of the box, there is only one for all domains (*), that is sql provider.

    <switchingProviders>
      <membership>
        <provider providerName="sql" storeFullNames="true" wildcard="%" domains="*" />
      </membership>
    </switchingProviders>

So, to make our Custom Membership Provider to work with our Domain(s). I have to change sitecore provider’s realProviderName=”switcher” and in the switchingProviders above, I have to add our Custom Membership Provider with our Domain(s).

Let’s create our domain first. To add the new domain, we have open the domain.config file from the Website\App_Config\Security folder and add the domain like below (highlighted).

<?xml version="1.0" encoding="utf-8"?>
<domains xmlns:sc="Sitecore">
  <domain name="sitecore" ensureAnonymousUser="false" />
  <domain name="extranet" />
  <domain name="default" isDefault="true" />
  <sc:templates>
    <domain type="Sitecore.Security.Domains.Domain, Sitecore.Kernel">
      <ensureAnonymousUser>true</ensureAnonymousUser>
      <locallyManaged>false</locallyManaged>
    </domain>
  </sc:templates>
  <!-- MyCompany domains -->
  <domain name="mycompany" />
</domains>

Next, we have to add the Custom Membership Provider in the web.config (highlighted) and change the realProviderName to switcher.

    <membership defaultProvider="sitecore" hashAlgorithmType="SHA1">
      <providers>
        <clear />
        <add name="sitecore" type="Sitecore.Security.SitecoreMembershipProvider, Sitecore.Kernel" realProviderName="switcher" providerWildcard="%" raiseEvents="true" />
        <add name="sql" type="System.Web.Security.SqlMembershipProvider" connectionStringName="core" applicationName="sitecore" minRequiredPasswordLength="1" minRequiredNonalphanumericCharacters="0" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="256" />
        <add name="MyCompanyProvider" type="MyCompany.Security.MyCompanyMembershipProvider, MyCompany.Security" connectionStringName="" applicationName="sitecore" minRequiredPasswordLength="1" minRequiredNonalphanumericCharacters="0" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="256" />
        <add name="switcher" type="Sitecore.Security.SwitchingMembershipProvider, Sitecore.Kernel" applicationName="sitecore" mappings="switchingProviders/membership" />
      </providers>
    </membership>

Finally, we have to add our Custom Membership Provider (highlighted) in the switchingProviders so that it get called for our domain.

    <switchingProviders>
      <membership>
        <provider providerName="MyCompanyProvider" storeFullNames="true" wildcard="%" domains="mycompany" />
        <provider providerName="sql" storeFullNames="true" wildcard="%" domains="*" />
      </membership>
      <roleManager>
        <provider providerName="sql" storeFullNames="true" wildcard="%" domains="*" ignoredUserDomains="" allowedUserDomains="" />
      </roleManager>
      <profile>
        <provider providerName="sql" storeFullNames="true" wildcard="%" domains="*" ignoredDomains="" />
      </profile>
    </switchingProviders>

That’s all the configuration needed. As far as the code goes, we have to implement ASP.NET Membership class. For a read only Membership Provider, as a minimum we need to implement two methods only. GetUser(string username, bool userIsOnline) and validateUser. I have also implemented the method GetAllUsers. I just wanted see bunch users from my domain in the Sitecore User Manager and use them to log into Sitecore. I am not going to copy and paste the code in the blog and discuss them. The code is very simple. You can download from Github.

After I deployed the code and the configs, I logged into sitecore as admin user. I can see the users from MyCompany domain.

User Manager

One thing to note that, Sitecore will look for the Anonymous user in the Membership Provider if ensureAnonymousUser=”false” is not included in the domain definition in the domain.config. If the Anonymous user doesn’t exists, the CreateUser method will called to create the Anonymous user.

Next, I tried to log on to the Sitecore Content Editor using MyCompany\user1. I couldn’t log in and got the access denied error.

Logon screen

I realized I haven’t added user1 in the Sitecore Client Authoring role. Once that’s done, I could log in to the site successfully.

 References:

Advertisements

About Himadri Chakrabarti

I am a software developer architect and a Sitecore MVP. My professional interest is everything and anything related to Software Architecture, .NET, Sitecore, Node.js, NoSQL etc. Outside of my profession, I am a hobbyist photographer. Link to my photography site http://himadriphotography.com/
This entry was posted in Security, Sitecore and tagged , . Bookmark the permalink.

One Response to How to Create – Sitecore Custom Membership Provider

  1. Pingback: A Sitecore custom provider gotcha - Kasaku

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s