CardSpace is a very promising new way of doing strong authentication across trust boundaries (it is much more than that, but there are already very good introductions and in-depth articles about it out there – see the links at the end of this post).
Adding CardSpace support to ASP.NET applications is very easy – you have to add a special <object> tag to a page and by submitting the containing form (or by doing a getElementById) you can trigger the client identity selector and transmit the encrypted XML token back to the web application. On the server side you can extract the token from the form, decrypt it using the private key of the server’s SSL certificate and process the contained claims. The <object> tag contains information about the card issuer, the token type and the required/optional claims, e.g.
<object type=’application/x-informationcard’ name=’_selector’>
<param name=’tokenType’ value=’urn:oasis:names:tc:SAML:1.0:assertion’ />
<param name=’issuer’ value=’http://www.leastprivilege.com…’ />
<param name=’requiredClaims’ value=’http://www.leastprivilege.com…’ />
<param name=’optionalClaims’ value=’http://www.leastprivilege.com…’ />
</object>
These are very low-entry technology requirements and can be done by any application that supports SSL, can emit HTML and decrypt standard W3C encrypted XML (e.g. sandbox.netfx3.com is implemented in ASP.NET whereas Kim Cameron’s blog uses PHP). Currently Microsoft only supports IE7, but there are plugins for Firefox and Safari available. For non-web applications, CardSpace support is integrated into WCF.
Due to the lack of broad support (OS, browsers and identity providers) and some other problems that need to get solved first (e.g. mobility of cards), most of you cannot just make an immediate switch to CardSpace – but it may be interesting for you to offer CardSpace authentication as an alternative to a password based logon.
To find out how hard it really is to add CardSpace support to an existing username/password based application, I started with a pretty standard ASP.NET application that uses all the usual technologies that Microsoft wants us to use (master pages, themes, the security controls, forms authentication, profile, navigation etc.). I will write about my experiences in a different post (e.g. about possible migration scenarios, how to integrate token/claims based authentication / authorization into you back-end without impacting your existing application and some management issues and procedures that need to be thought about).
One thing I wrote during that experiment is an ASP.NET server control to emit the right CardSpace object tag and the necessary JavaScript to invoke the identity selector on the client. This gives you a server side object to program against, makes maintenance easier and solves some problems you might run into when using CardSpace with master pages.
The CardSpaceSelector markup is straightforward:
<lp:CardSpaceSelector runat=”server” ID=”_selector”
IssuerType=”Managed”
Issuer=”http://www.leastprivilege.com/sts”
TokenType=”urn:oasis:names:tc:SAML:1.0:assertion”>
<lp:ClaimType>http://www.leastprivilege.com/…/givenname</lp:ClaimType>
<lp:ClaimType>http://www.leastprivilege.com/…/surname</lp:ClaimType>
<lp:ClaimType IsOptional=”true”>
http://www.leastprivilege.com/…/optionalclaim</lp:ClaimType>
</lp:CardSpaceSelector>
This renders an <object> tag, a clickable image and a JavaScript click handler that stores the encrypted XML in a hidden form field. On the server side you can retrieve the encrypted XML directly from the hidden field or from the XmlToken property of the control. Afterwards you can decrypt the token, e.g. using the TokenProcessor library from the SDK.
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
// retrieve encrypted XML
string xmlToken = _selector.XmlToken;
if (!string.IsNullOrEmpty(xmlToken))
{
try
{
// parse and decrypt the token
Token token = new Token(xmlToken);
// access claims
}
catch (Exception ex)
{ … }
}
}
}
CardSpaceSelector has a number of properties that can make your life easier, e.g.
IssuerType
This enum has two values ‘SelfIssued’ and ‘Managed’. If you select ‘SelfIssued’ then the issuer URI for self-issued cards will be emitted. If you select ‘Managed’ you have to set the issuer URI yourself.
Issuer and IssuerPolicy
Specifies the URIs for the issuer and the issuer policy.
TokenType
Specifies the token type. If not set, the URI for SAML 1.0 will be used.
HiddenFieldName
Specifies the name of the hidden field where the encrypted XML token gets stored on the client. The default is __XMLTOKEN.
XmlToken
Contains the encrypted XML token if an InfoCard was selected.
AutoPostBack
If set to true, the control will automatically do a postback after the user has selected an InfoCard.
ImageUrl
Let’s you change the default image.
In the attached zip you can find the source for the control alongside a little demo ASP.NET app that uses it. Be aware that the identity selector will only pop up if you are running over SSL – this is needed to encrypt the token and to create a unique PPID for your application.
Maybe this is useful for you. Write me if you have any comments, suggestions or found a bug…
Some additional reading
- A first look at CardSpace
- Step-by-Step guide to CardSpace
- Guide to supporting CardSpace in Web Applications and Browsers
- CardSpace on netfx3.com
- Scott Hanselman’s podcast on CardSpace
- Kim Cameron’s blog
- Identity 2.0 talk from Dick Hardt
- CardSpace forum
- Garrett Serack’s blog
- Richard Turner’s blog
- CardSpace plugin for Firefox
- CardSpace plugin for Safari
- A Guide to integrating with CardSpace
- CardSpace Technical Reference
Thanks for your help: Brock Allen, Jason Diamond and Christian Wenz
CardSpaceSelector.zip (38.55 KB)