A very common task in web development and architecture is setting up Single Sign On. Often times we have to configure a setup between different applications using different protocols and frameworks to make sure that our users have to log in only once. In the most common case the architecture is the following – you have multiple related but independent systems – some of them are using Sitefinity and some of them are not. A centralized access control mechanism is responsible to translate information around who this user is and whether he is authorized to get access to a resource. This centralized location is typically a protocol that ensures that all relying systems understand or translate the secured token that identifies the user. The abstract basics of this are simple and very well known.
In this blog post we are going to discuss the different techniques of achieving this, whenever you have the Sitefinity CMS involved in the SSO architecture. SSO between different Sitefinity applications is trivial and only requires configuration (as per this documentation article), The task becomes more interesting whenever the systems/tokens/mechanisms are different.
Here is the challenge: I want to implement SSO with a third party application/system or social media within Sitefinity CMS. How do I go about doing that?
The solution: In a few short words the solution is the following: You need 3 things:
- A unique identifier that will act as a username (we will see that this can be obtained through a ClaimsIdentity or any other mechanism exposed by the third party application)
- A provider which will recognize this identifier(We will see that this can be achieved by implementing a membership provider or creating the users that will have access)
- A way of securely communicating with the third party access control system and trusting the identities that it claims (we will see that this can be done through WS-Federation or any other standard supported by the third party system)
You just need to obtain the username of the current user from an identity provider that you trust and make sure this translates into a user object that Sitefinity understands.
We will see how Windows Identity Foundation automates and encapsulates most of these tasks, how you can deal with it in non-WIF scenarios and the different strategies to make sure the user that is in a single-sing-on interaction is mappable to a Sitefinity User Object.
Before we get started – it’s good to cover some of the basic terminology:
Claims Based Authentication – Instead of going into a dry definition I would rather use an example from this post– Explain Claims Based Authentication to a 5 year old – and here is an excellent explanation:
"Claims Based Authentication is about defining who you trust to give you accurate information about identity, and only ever using that information provided. My (the) go-to example is at a bar. Imagine for a moment that you want to get a beer at the bar. In theory the bartender should ask you for proof of age. How do you prove it? Well, one option is to have the bartender cut you in half and count the number of rings, but there could be some problems with that. The other option is for you to write down your birthday on a piece of paper to which the bartender approves or disapproves. The third option is to go to the government, get an ID card, and then present the ID to the bartender."
Now I am not certain that this is exactly what a 5 year old might relate to, but it’s important to mention that the Sitefinity part of this extends this metaphor a little – reading claims issued by a different application is similar proving your identity in a bar, while also having a tab at this bar. There is information that a trusted issuer (the Government or our well-beloved local DMV), but there is information about you strictly associated with this identity and stored in this bar. Having a tab in Sitefinity is actually quite important for a lot of the infrastructure. It's not necessary, but it's very key.
Windows Identity Foundation(WIF) – This is a set of .NET classes and libraries for implementing Claims Based Identity within your applications. Sitefinity utilizes WIF and some of it’s built in classes such as ClaimsIdentity and ClaimsPrinciple for authentication.
Tokens – those are protocol defined structures that are used for transferring the user identity. Tokens come in many different formats. SAML is a common format, but tokens can also come from the Kerberos protocol/Windows authentication as well as have their own specific implementation. Sitefinity uses an implementation of the SWT format, and the Sitefinity STS Web App act as a translator between different token formats. In the Bar metaphor this would be your ID card.
STS – or a Security Token Service – can be any application that is responsible for accessing the identity store . An STS is an application that you establish trust. In the Bar scenario this would be the Government, the DMV or another institution that you trust and that has issued your ID.
Relying Party (RP) – is any application configured to trust the claims coming from an STS. In our cases both Sitefinity and your other application have to be configured(in some way) to be relying parties of a centralized STS. In the metaphor this is the bouncer at the bar.
Azure ACS - is a very fancy STS. It's a service provided by Microsoft that is able to federate different types of identities coming from ws-federation or various social networks.
Identity Store – in a nutshell this is an application or API that has access to a user database and is responsible for actually authenticating a user(checking his credentials or claim against a database). We will see how there can be multiple hops towards an identity store and accessing this user database can sometimes be responsibility of a 3rd party application such as Facebook that only exposes an API. In our example this store is the ultra secret(or not-so ultra secret) government archive of all registered citizens/residents.
Provider – is a Sitefinity term for identity store very crucial to the extent of implementation of SSO. In the bar metaphor you can think of this as the software needed to store your bar tab and maybe even information on whether you are "on the list" or permissions to go to the VIP room.
Having covered that here are a number of things that you would need to know before we dive into specific implementation details.
What you need to know about Authentication and Authorization
The techniques that we are going to use in this blog post work with Sitefinity’s authentication and authorization mechanisms. A great reading to start with is this documentation article which describes in greater depth the Claims and Forms Authentication models in Sitefinity along with their implementation specifics. Here are some of the concepts that you will need to know in Sitefinity.
1) If you don’t explicitly require forms - use claims authentication.
This is a default in Sitefinity starting from version 5.0 and in case you are interested in Enterprise Grade SSO scenarios, it just makes sense to use this authentication mode as it provides very flexible methods around authentication and authorization. It also provides other benefits for abstracting complex protocol specific communication – as we will see in the ACS example below. Forms Authentication is kept for backwards-compatibility purposes.
2) There are two general methods of achieving SSO with Sitefinity.
In a technical sense there are of course many services and mechanisms and frameworks and protocols but from the viewpoint with Sitefinity we are going to place the methods that you can use in two buckets based on one simple question – whether you want to use Claims and WIF or not. In the first case – we are going to use a Security Token Service of any sort (in our example – Azure ACS) and let WIF take care of the communication, federation, authorization etc. In the second – we are going to have to implement the system specific authorization protocols and then rely on the easy to use APIs that Sitefinity provides – mostly the single AuthenticateUser method.
In the first case there is a bit more explanation that we will go through in this post, but almost zero code and mostly configuration. In the second it’s fairly straightforward on Sitefinity end, just a couple of lines of Sitefinity code to log the user, but it will contain a lot more code specific to your internal systems - more specifically around protocols transportation and security logic, which need to be fully implemented on your end based on your system of choice.
To revert back to my metaphor, imagine you are in the US and you have your driver’s license. You are fine with going into any bar and there is a mutual understanding between the bars that they trust this type of document, so as a bar owner it’s really not difficult for you to set up tabs for your customers with this type of ID and let them in - this is the equivalent to our WIF scenario. Now imagine you have forgotten your license and you just have a Bulgarian library card. In the real world nobody will let you in, but in SSO world if we had a way of communicating with – say – the Bulgarian consulate and have you video conference with your library card, if they recognize this type of document and have you in their records, and the bar trusts the consulate, then you are able to go in. As you see here – you have options to communicate with more systems and trust their tokens, but you are responsible to establish a secure communication, which is not an easy task. (Especially if you have ever tried to teleconference with the Bulgarian consulate).
3) You are going to need the Sitefinity STS Web App if you want to do SSO via WIF – this will be a key component in the cases where we use windows identity foundation. It is a very simple, very small application provided as an ASP .NET web site and it generally consist of an HTTP Handler and some helper classes for the token. The sole role of the STS is to get a token of any kind – in the Windows Authentication case this typically relies on the Kerberos protocol. It could also be a SAML token, SWT token or any other protocol that WIF recognizes – as long as we can use federation of any kind (ws-federation) and get a token from your system, you Authenticate in the STS Web App with this identity and this respectively goes to Sitefinity, since Sitefinity is a relying party of the STS. Sitefinity uses a variation of the SWT format and the STS Web App acts as a translator between this.
4) Key parameters that need to be communicated to any systems – the key parameters that we will use for the purpose of SSO boil down to just knowing the username (or a unique identifier) as well as the provider name. In both methods we will discuss here, all we will need is these two to successfully log in a user. Of course provider name is redundant in case there is only one provider.
5) Membership providers. Now you might be asking – why do we need providers if we are federating identity management only authorizing based on a third party system? And the answer to that is that knowing the identity of someone and a few claims around them is insufficient for a fully-fledged CMS infrastructure – you need to basically have a user object that the CMS can resolve on runtime. Same as the fact that you need to store the name and probably a unique identifier within the Bar tab software in order for the bar to trust you with things like getting free drinks. Sitefinity provides enough flexibility to decouple any logic around how and where users are stored through membership providers. They are the mechanism that basically boils down to an extensible GetUser method that can work with any kind of system or data, but it returns a Sitefinity User object, regardless of where we get the user from. Membership providers are a key concept in Sitefinity and any authentication mechanism (programmatic or not). Here are some things that are important to know about these providers.
a. Whenever a user logs into Sitefinity, his name or id is matched and verified in a Membership provider.
b. We can have as many providers as we want
c. Providers are independent of one another.
d. If you are not familiar with the provider model as a part of the Sitefinity architecture, you can look into this article. The general idea is that Sitefinity doesn’t care where users come from – the database, AD, Default ASP .NET SQL Provider or any other class that implements a few abstract methods such as GetUsers and ValidateUser.
e. A user is associated with an ID in Sitefinity, which in .NET takes the form of a GUID type. If your system does not rely on GUIDS then some mapping needs to occur and we will show techniques of how to do that.
6) Why having the user’s name verify in the particular provider in Sitefinity is important. The short answer to this is – you need it for a lot of the infrastructure. Technically you don’t need a provider in Sitefinity to know about a user with a particular name. Since Sitefinity uses Claims Based Authentication, you can simply trust a claim coming from your Security Token Service (STS). The basic principle of claims is that the STS claims – this user is “Greg” and we trust this claim. But that makes Greg a front-end user - it doesn’t give you much in terms of Sitefinity infrastructure, outside of the sheer knowledge that this is a user that has a unique identity claimed from an identity provider we trust and his username token is “Greg”. In effect this is an authenticated front end user. Whether you do SSO or not you need a unique User Object for Sitefinity infrastructure to facilitate the majority of management tasks (all back-end editing, permissions and a lot of the front-end features).
This is the object that gets associated with your User Profiles, your roles, your permissions, user segments etc. If you have browsed around different social login or SSO enabled sites on the web, it is very evident that it stores a unique ID of sorts and associates a bunch of other data with it. So the different techniques described here, although easy to set up and get a particular claim, will talk about how to make sure you have that user verify in your provider.
Having covered these basics here is how it actually work in different scenarios.
The two SSO Methods covered in this post
As mentioned above - in this blog post we are going to cover two basic methods to tackle these kinds of scenarios.
- Strategy A: Using the internal APIs and not relying on Claims
- Strategy B: Using Claims and a Security Token Service
At this point, if you are the developer or IT Manager responsible for maintaining SSO deployments you probably know all details around your infrastructure with great detail. For example the applications that you want to integrate with may use Windows Authentication, SAML tokens, Client Certificates, OAuth etc. Both those strategies are feasible for most cases. Technically scenario B is a bit more restricted and applicable only when you can get a token out of a Security Token Service that is one of the following types:
- Forms authentication
- Client certificates
- SAML tokens
- Other extended token types such as SWT
This accounts for a great number of systems - on-premise federation services (ADFS 2.0) or cloud based Services(Azure ACS), a hybrid of both(ADFS + ACS) or any type of STS that supports WS-* standards. Typically WS-* standards are considered a beast that nobody really wants to deal with, because they have a complex architecture, but the good news is that because of how advanced the frameworks around this is, these contracts are set up entirely through configuration. In any case it’s always good to understand what is going on behind the scenes and wrap your head around the concepts and I can recommend this article for an in-depth exploration of the topic.
Now from all of this it may sound that Scenario B is all too enterprise-y and a good question might be - what about social login. It is worth mentioning there are different services and identity providers out there that already take care of the heavy lifting and are able to provide claims from a social provider like Facebook or Google to Sitefinity.
Azure ACS as one example can generate claims from Google, Yahoo, Facebook, LiveID etc, therefore Strategy B may be applicable for a much wider set of cases, without you having to do a lot of extra work and just by using a service. ACS has the down side of not supporting Twitter, but there is a wide variety of services that do(Auth0 looks very promising for example).
On the other end if you decide not to go to an STS the WIF way, or your application is for example Java based and does not allow this type of infrastructure altogether, Sitefinity can also take care of that. This is where we fall under Strategy 1, but in this case the entire transportation layer – how we talk to your 3rd party app, how we obtain authorization and a user token, how we establish trust, is in your hand. So whether you use OAuth, redirects, other types of handshakes and what type of tokens you pass is largely in your responsibility. As we can see in some examples this also carries certain cases where it’s suitable.
Here is a compiled list of questions that can summarize the difference between the strategies.
Using internal APIs and not relying on Claims
Using Claims and a Security Token Service
What happens once I receive a token from my third party service?
Authorization and authentication is handled through an API call
Authorization is handled internally in Sitefinity
How much do I have to be concerned with transportation, protocol and token specifics?
It’s a lower level approach: You need to implement the way users are authenticated and tokens are obtained through any way your 3rd party system provides
It’s a higher level approach: Communicating with the STS is abstracted and achieved only through configuration
Which Identity Providers could this work with?
Has no restriction on the communication protocols and token formats and works with practically any Identity Provider
Has certain restrictions of the token formats, but can work for most Identity Providers either directly or through a "middle man" service
Where is most of the complexity?
The complexity is mostly in the implementation of the security and transportation of federation metadata and largely depends on the third party Identity Provider's specifics, how well is it documented, etc.
Complexity is mostly in the conceptual understanding of Identity and Federation and bringing all your apps within that infrastructure. The actual implementation is easier and more manageable.
How is security handled – handshakes, token encryption, authentication handlers, 301 challenges etc.
You need to take care of security
WIF takes care of security
How much control do I have?
Being lower level – it gives you more control over any granular aspect of the transportation.
Being higher level – it’s not concerned with the specifics of the transportation. It still gives you all the existing extension points that Sitefinity provides.
What will I need as parameters from my 3rd party service
A unique identifier(username) that Sitefinity will recognize within a provider
A unique identifier(username) that Sitefinity will recognize within a provider
What about the username and the membership provider
Before I go into the two scenarios with samples and instructions around their specifics, let me clarify what we mean by needing a username in the context of Sitefinity(a provider).
As explained above Sitefinity has the requirement to have a membership provider recognize the username that we are authorizing access through means of SSO. So in essence this is a user known to your third party application or Identity Provider and unique. Sitefinity will also need to be able to recognize this user as a user object in Sitefinity language. In the Sitefinity world a membership provider is just a class that is used for managing any of the users in Sitefinity. In real time all we need it an object of type user and because of the provider pattern, we don’t concern ourselves with where this object comes from. In implementation terms this means that we need to have a GetUser method in our provider that based on the name identifier returns a unique Sitefinity User object. There are two strategies to go about this:
Strategy 1: Create a membership provider.
Let’s walk through an example and take the simpler case of Windows Authentication which comes out of the box with Sitefinity. What happens there is the following – we are logged into our machine, Sitefinity knows about this account and lets us in. In technical terms Sitefinity is a relying party and it delegates authentication to a very small service called Sitefinity STS (this is an application that comes with Sitefinity). The Sitefinity STS in its term has windows authentication turned on.
On a lower level a number of redirects and authorizations happen based and finally we get an object – in WIF terminology a Principal - that carries all its claims, including my username and the roles that I have assigned in AD. But you can think of this claim this claim as essentially a dictionary, right. It says something like Username:Yankova, but the only magical thing is that it comes from an issuer that we really really trust. This gets to Sitefinity in the form of an encrypted token and Sitefinity not only acknowledges that this user is unique and has certain claims and is therefore authenticated, but it also associates a User object to it (with Guid, LoginStatus and everything), because the LdapProvider has a GetUser method that is able to retrieve an object based on that username claim that we have.
Somewhere in the authentication handler Sitefinity calls something like this pseudo code.
User CurrentUser = GetUser(“yankova”)
Which actually returns an object since the LDAP provider in itself can talk to active directory and get my user object, then cast it to the Sitefinity User Type. And now the entire Sitefinity infrastructure works for me just as if I were a user in the default Sitefinity database. I am even the administrator.
Same with roles - if you have the Ldap Role provider configured these roles are also going to be associated to your user as well as manageable through Sitefinity.
This overall encapsulates the major role of the provider pattern in Sitefinity
- Have multiple independent ways to manage data sources. In this case you can have Default and LDAP providers at the same time
- have the ability to implement them to read from any data source through a few methods defined in an interface
- Have the data objects that are coming from this provider(in our case users) play with the full infrastructure of Sitefinity – permissions, profiles, personalization, ecommerce, etc.
The membership provider strategy allows us to use literally any provider you want. The default Sitefinity provider doesn’t make much sense in these scenarios but you can use LDAP, The Default ASP .NET SQL Membership and Role provider(documentation), any class that inherits Sitefinity’s MembershipDataProvider abstract class as well as any class that inherits .NET’s MembershipProvider abstract class.
Strategy 2: Creating users upon registration
Membership Providers are great for user repositories in our control, but for example Facebook has a billion users. We can’t really implement a provider for all their user data(well - unless we are really, really good hackers.)
And it doesn’t make any sense to. Notice how any application that relies on Facebook as social login has a notion of the users identity and somehow associates it with a unique identity provided by Facebook. And that is the strategy that we can use in Sitefinity. Add a Facebook register button and create a unique user in a data store with the same identifier. Then regardless of what SSO implementation scenario we are in – whether we are passing a claim or calling AuthenticateUser with that unique identifier, our user will be a fully-fledged Sitefinity user and not just a limited front-end user. For that we would only need to programmatically create a user the first time that they register.
Now that we have discussed the membership provider strategies, you have a better understanding in how our infrastructure fits yours. In the upcoming blog post we are going to look at how the specific implementations would look like.