Developing a minimal STS with ADFS "2" Identity Framework (Part II: Issuing Managed Cards)

Here we are again. I can't believe it's already THREE weeks I've posted part I of this post! Well, this Saturday I leave for EU where I'll spend a couple of weeks of vacation (Italy & Poland): so I better get to work and finish what I've started. In this post we will take care of the managed card issuance code.

I am a bit reluctant to make this post. At this point I know that the code necessary for issuing cards with the ADFS "2" Identity Framework will change significantly in respect to what I've shown @ TechEd; hence I don't want to produce one of those information fragments that in the future will show up in your search queries but will not really help you to work with the most recent bits. We've all been there, especially with some of our technologies that underwent significant changes between preview bits & RTM. On the other hand I don't want to leave the scenario incomplete, hence I decided I'll use some pseudo code: I'll use code regions for showing what happens from the functional perspective, but I will not expose you to a syntax that is already old today. Please keep that in mind while you go through this section of the walkthrough; I'll try to focus more on the design considerations that the syntactic sugar. Once we'll have a chance of showing some more recent bits, we'll resume the usual level of detail. That said, let's dive in!

Let's create a web page for managed cards distribution

In Part I we created a website project (STS2); we configured it for using the federatedAuthentication httpmodule; we created a ScopeProvider class, where we placed all our logic for populating claims; we derived a class from SecurityTokenService and tied it to our custom ScopeProvider; finally, we added an SVC file that, using the WindowsInformationCardServiceHostFactory, provides all the necessary configuration for our SecurityTokenService to listen for kerberos-secured RSTs. We hit the endpoint with the browser and we verified that at least the metadata generation works. Hey, that was much faster than last time :-)

Now that we have an STS up & running, we need to issue to our potential users suitable managed cards that will make good use of it.

The topic of managed cards is a big one per se, and I won't repeat it all here. Let's just say that managed cards are XML documents which contain all the necessaire for understanding which kind of tokens can be emitted by a certain STS (=claims, format) and some hints about how that STS would authenticate requests (this post is a bit outdated, but it can still give an idea). In respect to authentication, managed cards come in four flavors (2 less than quarks):

  • Kerberos
  • X509 Certificates
  • SAML from personal cards
  • Username/Password

If my STS would be accepting RSTs secured by X509 certificates, for example, then I'd have to embed in the card itself some instruction about which certificate in particular should be used (see this post). This also means that I should have that information at the moment in which I am generating the card file. The same goes for managed cards backed by personal cards: at the moment in which I generate the managed card, I need to know the PPID of the personal card that is intended to back it. In both cases, that would mean that my card generation logic would likely need some input from the user (like the backing personal card). Since I am especially lazy, however (or rather because I know that writing code on stage is a very unhealthy sport and I tried to keep everything a simple as possible), our STS expects kerberos protected RSTs hence we can generate suitable cards without any input from the user. So we'll just create a simple web page featuring a button that will launch code for generating and downloading a kerberos-backed managed card tailored to our STS & claim set parameters.

When we created the website project we didn't delete Default.aspx; let's just go ahead and drag on it a simple button.

 image

Let's double click on it and fill it with the code for generating the card and sending it back with the http response:

image

And here there's the meat of card issuance (please remember what I wrote at the beginning of the post about the API changing!!!).

The green rectangle shows the click event handler of our button (in full laziness tradition, I didn't change the default name).

In the red rectangle we show the core of our functionality: we obtain a reference to our STS instance, we set a couple of minor options (card name & background image), then... we just ask the STS endpoint to issue the card! Just compare this code with this example, where we write everything from scratch: pretty good!!! The trick is that the STS endpoint knows everything there is to know about the card: the claims (remember the methods we wrote for the ScopeProvider?) and the policy used for accepting RSTs. Since in the kerberos case we don't have to feed further info, that's all we need for issuing the card (if we'd have to feed in further info, like the PPID in the personal card backing case, this would be the place to do so). Note that the STS is not necessarily the only entity from where we can extract the information necessary for emitting the card, but you get the idea.

The blue rectangle shows some lowly serialization code; note that the contenttype is crafted in a way that will launch (modulo user consent)on the client system the application associated with managed cards (in our case, CardSpace).

That's it! Let's spin the page for a test ride:

image

Let's click on the button, and... surprise.

image

Our very own managed card is coming down! Let's open it:

 image

That's our card, ready to be installed via the new sleek 3.5 experience. If we would have saved it, what we would have seen?

 image

Here there's the managed card file, opened in XML Notepad 2007: the file in itself is full of information, so I'm not showing the raw XML. Want proof it is really our card? The green circle shows the address of our STS; the blue circle highlights that we are using kerberos; the red circle shows out custom claim, https://schemas.maseghepensu.it/claims/accent, as we defined it in Part I.

 

That was pretty fast & painless: in few lines of code, we added to our website the capability of issuing managed cards for our STS.

What's left for closing our scenario? We need a relying party that asks for our cards. That's the topic of part III, that I'll try to write before leaving for vacation (or my punishment will be to do it on the plane on a tiny, tiny screen :-)).