Wednesday, August 24, 2011

ADFS 2.0 – The quest for customizing ADFS sign-in web pages


The passive WS-Federation protocol becomes an important part of the architecture of our applications. A standalone ADFS works like a charm, also it’s fairly easy to write a custom STS so that the RP application does not not see any difference in the communication protocol (and can be switched between ADFS and a custom STS).

One of the drawbacks of ADFS is that it’s tightly bound to the Active Directory. You can login using username/password and both attributes always come from AD. There’s no way to add your custom authentication logic like “login using email/password” or “login using credentials from the database”. Windows account or nothing. Although you could expect something like “ADFSMembershipProvider” (like the one we have in ASP.NET), there’s none.

To ADFS or not to ADFS

Should one then chose ADFS or rather another STS in a production environment? Good question. Take a look at StarterSTS, it’s what ADFS should be. It supports variety of authentication sources, including custom MembershipProviders. What’s the reason then to stick with ADFS?

To me, the only but damn important reason is that ADFS is an official and mature tool, blessed by Microsoft. There is a difference between “we use the ADFS 2.0” and “we use a custom authentication tool”, no matter how closely such custom tool mimic the way ADFS works and who wrote it.

Towards ADFS customization

Suppose then that, like us, you’ve decided to stay with ADFS. And still, you need a way to customize the authentication logic. The ultimate goal would then be:

The ADFS should be able to pick up an arbitrary logic of authentication (=I want to have something like MembershipProviders for ADFS!)

One of the primary sources which suggest that this is possible is this blog entry by the Identity and Access Team. The entry shows a way to modify the code of the ADFS login page so that it picks up a custom authentication logic, involving a custom STS implementing a WSTrustFeb2005 endpoint.

So what’s the big deal then if someone has already described the solution? Well, take a look at this blog entry and try to follow it.

Have you failed? Well, welcome to the real life.

In fact, the note is rather concise but a lot of work must be done to actually follow it. And it could fail at many, many different levels and stages.

The roadmap

The roadmap is as follows:

  1. Passive federation of ADFS with C-STS (your custom STS)
    1. Implement passive STS functionality in C-STS
    2. Configure the federation between ADFS and C-STS
    3. Test the federation
  2. Active federation of ADFS with C-STS
    1. Implement your custom token handler
    2. Implement WSTrustFeb2005 service endpoint on C-STS
    3. Modify ADFS login logic to authenticate users in C-STS using the WCF endpoint
    4. Test the federation

There is a motivation behind this - the active federation, described in the Identity Blog entry will not work until you correctly federate the ADFS with your STS for a passive scenario. You have to then move on slowly, step by step, and validate each single step until the goal is reached.

And the last thing in this entry – it took me about 5 days to make it work. I will describe all the steps and possible pitfalls in upcoming entries.

No comments: