SharePoint 2010 brought us the whole new authentication world – Claims-Based authentication, based on the Windows Identity Foundation. To go through the whole claims-based logic would take too much time and space on this blog, but it’s nevertheless crucial for understanding the whole concept. If you haven’t already seen it, please take a look at a great interview with Microsoft’s Venky Veeraraghavan, one of the people who have designed the whole concept.
What I will focus on now is how to use the claims-based authentication to set up a combined, Windows Authentication and Forms Based Authentication (FBA) on a SharePoint Web Application. It’s a fairly common scenario – you have your internal people, who are members of the domain, and external partners or salesmen who have to use resources in your intranet, but they are not members of your domain.
Way back, in the times of MOSS 2007, there was a Form Based Authentication. There was even a way to combine it with Windows Authentication. But it was not an easy thing to do. And, even once it was done, it was always a funny thing to observe an user who has just authenticated over FBA trying to open a Word document. After clicking three times on the “Cancel” button in the great Windows authentication popup, the document opens anyways. Sometimes.
Now, try to explain that to the customer…
It ended up with administrators creating domain accounts for external people just because of the SharePoint. Man, the loved it.
But, as we have said earlier, everything is claims and good now. Except if you chose the classical authentication mode when you are creating your SharePoint web application, which is the default setting. But let’s not get into it…
Anyway, it works now. You do have to change some defaults, you do need some afterwards (no, Microsoft still doesn’t want us to give up on the SharePoint-Voodoo), but – it works.
Back to the future
Let’s think of the following scenario. We are a rock label. Our employees have the following usernames: bspringsteen, jcocker, bvox, mjagger and smacgowan. We make a great business, earn lot of money, and we have decided to support some poor jazz guys. We have an old web application, maybe even PHP with MySQL database, which is used by those external jazz people. It means, they already have usernames and passwords there. Now, we want to give them the access to our brand new SharePoint portal, but we don’t want them in the AD. They are not the rock’n’roll people, after all. We want to use existing authentication (usernames and passwords for the old PHP application), and just to give them necessary rights on our SharePoint portal.
Building a custom ASP.NET membership and roles provider
The first thing we have to do is to write a custom ASP.NET membership provider. It’s peace of code which will tell us who can authenticate, and who can’t. That’s nothing new, but it has to be done.
1. Create a new .NET 3.5 class library in VS 2010
2. Create two new classes in the class library, one has to inherit from the MembersipProvider class, and the other from the RolesProvider class (both in System.Web.Security):
Now, let’s take a look at the “ShareDoveMembershipProvider” class. You have to implement the following methods:
You see, this is the place where you implement all your user-authentication logic. Let’s keep the things simple for the demo purposes, and let’s hard code our Jazz-people as users in this class.
In the real life you would of course talk to the MySql database mentioned in the example above which contains usernames and passwords, or to the web service, or to a sharepoint-voodoo-priest or whatever. Right now, as we said, just a hard coded example:
Now we have to do the same thing with the ShareDoveRolesProvider class – this is where we implement our roles logic – which user belongs to which internal role. Don’t mix this up with SharePoint roles – they still exist, SharePoint still takes care of the authorization, but there might be a case where we want to know the internal roles of the source system. It means, we might want to know who of our jazz people play piano (they are in the “pianist” role), and the roles provider can give us this answer.
The following methods have to be implemented in the Roles provider:
And again, let’s do some hard coding for this demo purposes. Here is how the class should look like:
So that’s it, we have our custom ASP.NET membership and roles provider that is authenticating our jazz people. Finally, we have to do with it is to sign it, and to throw it to the GAC. Yes, it has to go there.
(gacutil -i ShareDove.MembershipAndRolesProvider.dll)
Creating a Claims-based Web Application
The next step is to create a SharePoint Web Application which will used Claims-based authentication. As we said, the classical mode authentication is still the default mode, so we have to change it manually:
(click on the picture for the full size)
We see that we explicitly have to choose the “Claims based authentication”, and to select the “Enable Forms Based Authentication (FBA)” option.
We also see that we have to set the “ASP.NET Membership Provider Name” and “ASP.NET Role Manager Name”. At this point just give some names which make sense (these names will be later displayed to your users!), but write them down in the Notepad since we will be using it in the SharePoint-Voodoo session that is coming.
OK, now we have just created a SharePoint web application, and we told to the Web Application that we want to use a custom ASP.NET membership and role providers for our Form Based Authentication, and that they are called, for example, “ShareDove Membership Provider” and “ShareDove Roles Provider”.
Now, we have to associate somehow this canonical names with our class library which is waiting in GAC to be used. The most logical and straight-forward way is to do it in the web.config.
And since it is that logical, we have to do it three times. Three. The magical voodoo number.
This is not a joke. We have to register our assembly in the web.config of the newly created SharePoint web application (ok, that makes sense). Then in the SharePoint STS (Security Token Service – a SharePoint Service Application which is handling whole this claims thing). OK, somehow I can understand that as well. But then, we have to register it in the web.config of the Central Administration application as well. Voodoo. No other explanation for that.
(Applications where we have to edit the web.config)
Luckily, at all three web.config files we have to enter the same peace of code. Under the <system.web> section, we have to add our new providers in the “membership” and “roleManager” sections as following:
WARNING 1: Leave the existing providers alone, otherwise the SharePoint-Voodo-Gods will take revenge on you.
WARNING 2: Don’t copy my assembly names and tokens – they won’t work at your SharePoint.
WARNING 3: the “name” attribute of both providers have to be EXACTLY the same as entered when creating the web application.
Creating the Site Collection and testing the whole thing
Now we can create a SiteCollection on this application as we are used to.
And, when we try to open our site collection, voila…
SharePoint asks us how we would like to log on!
Let’s try the Forms Authentication, and let’s try to sign in as a great jazz pianist Jelly Roll Morton:
OK, it’s obvious that good ol’ Jelly doesn’t have any rights on our SharePoint portal yet! We did authenticate him (“You are currently signed in as: jelly roll morton”), but, authorization is still on the SharePoint part of the game. Poor Jelly can’t do anything yet.
Let’s sign out, and sign in again as Administrator (or some other Very Powerful User) using the Windows Authentication. Let’s create a SharePoint Group called “Jazzers”, and fill it with some users:
OK, here is our new people picker! We see, on the left side, more groups, one of them being the “Forms Auth” – that is where we find our jazz people. Let’s select them all in our “Jazzers” SharePoint group, and let’s give some rights to that group:
When selecting the FBA users, if we click at the user information, we see the following:
User Information panel gives us all the information we provided through our ASP.NET membership provider, and it clearly states the provider which gave the info (“ShareDove Membership Provider”)
We can now log out as the Administrator, and try to log in as Billie Holiday using the FBA again:
So, we see, it really does work! Our external users can do exactly what we authorize them to do. Even open the Word documents!
Hope this helps someone.