[Edit: Added Silverlight SxS con WPF/E]
In short: this is a tutorial on invoking Cardspace from a Sliverlight [WPF/E] control and how to use Silverlight [WPF/E] for showing data from a token. So easy that a long haired architect can do it 🙂
Silverlight [WPF/E] is Microsoft's technology for developing rich internet applications, but it is also going to be CROSS PLATFORM (the CTP it is already available for Mac). In light of the awesome work of the Bandit guys on an identity selector on other platforms, I believe it is important to start thinking about how to use this new RIA technology together with identity.
In recent times I'm hearing more and more people interested in Rich Internet Applications, or RIA. That usually brings the discussion pretty quickly on Silverlight [WPF/E], our cross platform presentation technology that leverages a subset of XAML for doing cool things inside your browser. I am often asked how to plug CardSpace into it, so I thought to put toghether a post that shows how to do that.
As you know it's few years that I am a server guy, so I don't spend too much time on colorful stuff: however I also like to cross pollinate different technologies, and I especially love to do it with CardSpace (I did it with WPF, with WF, with WCF and WPF). Yesterday night I downloaded the WPF/E SDK, the WPF/E runtime for Windows and blocked 1 hour on the calendar of my excellent colleague Laurence Moroney, probably the best mentor I could get for ramping up super fast on this technology. Thank you man!!!!
My objective was to use that hour for coming out with a full Silverlight [WPF/E]+CardSpace PoC, namely: 1) I wanted to invoke the identity selector from a Silverlight [WPF/E] UI 2) I wanted to render some info pulled out from a token. As you can see, there's no buisiness scenario involved: this is pure syntactic sugar, how to get the two to work together. As I hoped, we declared mission accomplished after just 35 minutes 🙂 below the details.
The steps are
- Install the Silverlight [WPF/E] necessaire
- Familiarize with the basic Silverlight [WPF/E] project
- Modify a cardspace login page for using a Silverlight [WPF/E] control to invoke the Identity Selector
- Modify an ASPX page for showing some claims values using Silverlight [WPF/E]
Install the Silverlight [WPF/E] necessaire
If you are new to Silverlight [WPF/E]: you can get all the details here. However, for the purpose of our discussion: Silverlight [WPF/E] is a subset of XAML, the markup language behind WPF, that allows you to deliver in the browser interactive applications containing animation, audio, video, graphic, text and obviously interactivity. The interesting point is that Silverlight [WPF/E] works CROSS PLATFORM, that is to say that your Silverlight [WPF/E] application is available on multiple browsers and multiple platforms (WIndows and Mac). In practice, there will be a lightweight plugin that will enable the browser to understand and render XAML code. Neat!!!
The most recent build is the February CTP. You can get the runtime from here, while the SDK is here. If you use VIsual Studio 2005, after the setup go in the SDK menu folder: there you will find an entry for installing a Visual Studio WPF/E project template, I suggest installing it: it makes things easier for this tutorial.
Note: if you want to nurture your inner designer, Expression Blend is the ideal tool for the task. I am not considering it in this post, since I suspect we are all thick skinned protocol guys around here 🙂
Familiarize with the basic Silverlight [WPF/E] project
In order to avoid wasting Laurence's time, yesterday night I familiarized with the basic Silverlight [WPF/E] project.
If you installed the VS template, go ahead and create a new Silverlight [WPF/E] project. Don't change anything from the defaults. The solution explorer ends up with the following structure:
The file plugin.xaml contains the UI of our control. The syntax is very straightfoward: this is a canvas called button, containing a rectangle and the text "Click Me". There's no binary black magic, this is just plain old human readable XML:
The file Default.html is the only page of our site. The code is, again, straightforward:
The body contains a simple form, with a named div and a single call to function agHost. It's not hard to imagine the purpose of the function call: we use it for instantiating in the page our Silverlight [WPF/E] UI. You can notice in the parameters plugin.xaml, the name of the first file we examined in the solution.
We are left with the JS files.
I won't go into the details of aghost.js, nor should you: its function is well explained by the file header, that I am copying below.
If you hit F5, you'll see a page with a single button that shows an alert when clicked.
"Doh", some of you will say. Well, take into account that we didn't change a tad of the template project: I wanted to understand how Silverlight [WPF/E] works, and for that we have to keep the signal/noise ratio to a mangeable value. You are of course invited to make things prettier 🙂
Modify a Cardspace login page for using a Silverlight [WPF/E] control to invoke the Identity Selector
Now we get to the interesting part. It is all very easy: however, if you are not familiar with the basic CardSpace samples from this point on it will be difficult to follow. I recommend you to download and play with those samples, since you'll have to modify them with what we have just learned about Silverlight [WPF/E]. They are very clear and straighforward, in true Garrett style: from my good friend and book buddy, I would not expect anything less 🙂
Let's get to work. Open your favourite Cardspace sample solution (if you use those samples, I would suggest exercise 3 or 4). What we want to obtain is very easy: we have to elicit the form post from our Silverlight [WPF/E] button instead of the usual HTLM one.
First thing, we copy all the necessaire in the cardspace solution (or in the folder, if you are not using visual studio). The necessaire in this case is the JS directory, with aghost.js and eventhandles, and the XAML file (which for the occasion I renamed LoginControl.xaml).
Once we have copied those, we have to modify the cardspace login page by 1) getting rid of the current mean of POSTing the form (usually a button with type submit) and 2) pasting in the XAML hosting code we have seen above. We will worry about modifying the logic wired to the Silverlight [WPF/E] control in the next steps.
Above you can see the modified HTML page. The green and yellow highloghts are the same fragments we had in the pure Silverlight [WPF/E] sample, apart from the name of the XAML file.
The light blue highlight shows the usual cardspace object tag, in the usual form. The form method is submit, as always; we POST to a known page, that we will craft in the last part of the tutorial.
In this moment, the HTML page does not contain anymore an element that could trigger the POST of the form. We are going to add that capability to the Silverlight [WPF/E] UI by modifying the code in eventhandlers.js:
So, we accomplished our first task. We invoked the selector from Silverlight [WPF/E].
Modify an ASPX page for showing some claims values using Silverlight [WPF/E]
This part is slightly trickier, but still very easy. What we want to prove is that it is possible to use Silverlight [WPF/E] for rendering data extracted from the security token we receive from CardSpace.
The XAML code is, again, just plain XML; as such, we can manipulate it as we like. Server side or Client side, it does not matter. For the purpose of the example, and for the sake of clarity, I have chosen the method that is the simplest to understand: do not take this as best practice.
In practically all web based CardSpace samples, we make use of the helper classes contained in TokenProcessor.cs. Thanks to that code, executed on the server by an ASPX page, we can deserialize and decrypt a security token for accessing the claim values. Hence, all we have to do is taking those values and injecting them in the XAML code that will render them. The operation is made even easier by a nice property of the XAML code: it can be inlined in the page. That is to say, we can generate the XAML directly from the server code with the values we need. We have just to use a slightly different syntax when we invoke the aghost function.
Below I paste the code of the page that applies considerations just made: don't get scared by its lenght, I will re-explain the concepts above function bu function by referring to the various colored regions of the source.
The top of the page contains the usual <%@ directives for importing the needed assemblies. We need IdentityModel and the TokenProcessor.
The turquoise area is a string, called stringvar, containing XAML code. It is cut short for clarity, however it contains a bunch of labels all rotate at different angles. The text ('String 1', 'String 2'...) is at this point just a placemark for the claim values.
The red area contains the classical TokenProcessor code: we get the content of the token that was POSTed to us, and we deserialize it in the Token class. Once we have a Token instance, we extract the claim values and we use them for replacing the palceholders in the variable containing the XAML code.
The we have the actual HTML page. In the header we have the usual import of aghost.js, in green. The really interesting part is the pink text: we have a script, of MIME type text/xaml, which contains the rendering of our xaml code. The script has id WPFeClaims.
Finally, the yellow part is the XAML instantiation. Notice that the SourceElement parameter refers to WPFeClaims, while the Source file parameter is now null.
That's it, this is all we have to do! If we go ahead and we send a card, the result looks similar to the image below:
Again, please remember that the images above do not give justice to the potential of Silverlight [WPF/E]: I just made a dull PoC.
As I hope the above demonstrated, integrating Silverlight [WPF/E] and Cardspace is very easy: so, if you want to make a RIA you don't have any more excuses: remember to add CardSpace support and make your application a good citizen of the Identity Metasystem! 🙂
PS: I know, an example would have been handier. However the tutorial is a good forcing function for really understanding how it works, since you can't skip directly to the solution. However, if you want me to package the above in an example please let me know: if I receive enough requests I'll definitely do it.