One of the projects that’s been kicking around in the back of my head is how to make Windows Phone 7 applications able to authenticate against a Windows domain. This is a must have for enterprise developers if they want to use the new platform.
There were a couple ways I could do this, but keeping with my Claims-shtick I figured I would use an STS. Given that ADFS is designed specifically for Active Directory authentication, I figured it would work nicely. It should work like this:
Nothing too spectacularly interesting about the process. In order to use ADFS though, I need the correct endpoint. In this case I’m using
That takes care of half of the problem. Now I actually need to make my application call that web service endpoint.
This is kind of a pain because WP7/Silverlight don’t support the underlying protocol, WS-Federation.
Theoretically I could just add that endpoint as a service reference and build up all the pieces, but that is a nightmare scenario because of all the boiler-plating around security. It would be nice if there was a library that supported WS-Federation for the phone.
As it turns out Dominick Baier came across a solution. He converted the project that came from the Identity training kit initially designed for Silverlight. As he mentions there were a few gotchas, but overall it worked nicely. You can download his source code and play around.
I decided to take it a step further though. I didn’t really like the basic flow of token requests, and I didn’t like how I couldn’t work with IPrincipal/IIdentity objects.
First things first though. I wanted to start from scratch, so I opened the identity training kit and looked for the Silverlight project. You can find it here: [wherever you installed the kit]\IdentityTrainingKitVS2010\Labs\SilverlightAndIdentity\Source\Assets\SL.IdentityModel.
Initially I thought I could just add it to a phone project, but that was a bad idea; there were too many build errors. I could convert the project file to a phone library, but frankly I was lazy, so I just created a new phone library and copied the source files between projects.
There were a couple references missing, so I added System.Runtime.Serialization, System.ServiceModel, and System.Xml.Linq.
This got the project built, but will it work?
I copied Dominick’s code:
private void button1_Click(object sender, RoutedEventArgs e)
_client = GetWSTrustClient(
new UsernameCredentials("username", "password"));
var rst = new RequestSecurityToken(WSTrust13Constants.KeyTypes.Bearer)
AppliesTo = new EndpointAddress("[…]")
_client.IssueCompleted += client_IssueCompleted;
void client_IssueCompleted(object sender, IssueCompletedEventArgs e)
_client.IssueCompleted -= client_IssueCompleted;
if (e.Error != null)
var token = e.Result;
button2.IsEnabled = true;
GetWSTrustClient(string stsEndpoint, IRequestCredentials credentials)
var client = new WSTrustClient(new WSTrustBindingUsernameMixed(),
new EndpointAddress(stsEndpoint), credentials);
To my surprise it worked. Sweet.
This left me wanting more though. In order to access any of the claims within the token I had to do something with the RequestSecurityTokenResponse (RSTR) object. Also, how do I make this identity stick around within the application?
The next thing I decided to do was figure out how to convert the RSTR object to an IClaimsIdentity. Unfortunately this requires a bit of XML parsing. Talk about a pain. Helper class it is:
public static class TokenHandler
private static XNamespace ASSERTION_NAMESPACE
private const string CLAIM_VALUE_TYPE
= "http://www.w3.org/2001/XMLSchema#string"; // bit of a hack
public static IClaimsPrincipal Convert(RequestSecurityTokenResponse rstr)
return new ClaimsPrincipal(GetClaimsIdentity(rstr));
private static ClaimsIdentity GetClaimsIdentity(RequestSecurityTokenResponse rstr)
XDocument responseDoc = XDocument.Parse(rstr.RequestedSecurityToken.RawToken);
XElement attStatement = responseDoc.Element(ASSERTION_NAMESPACE + "Assertion")
.Element(ASSERTION_NAMESPACE + "AttributeStatement");
var issuer = responseDoc.Root.Attribute("Issuer").Value;
ClaimCollection claims = new ClaimCollection();
foreach (var c in attStatement.Elements(ASSERTION_NAMESPACE + "Attribute"))
string attrName = c.Attribute("AttributeName").Value;
string attrNamespace = c.Attribute("AttributeNamespace").Value;
string claimType = attrNamespace + "/" + attrName;
foreach (var val in c.Elements(ASSERTION_NAMESPACE + "AttributeValue"))
claims.Add(new Claim(issuer, issuer, claimType,
return new ClaimsIdentity(claims);
Most of this is just breaking apart the SAML-goo. Once I got all the SAML assertions I generated a claim for each one and created a ClaimsIdentity object. This gets me a step closer to how I wanted things, but keeping the identity around within the application is still up in the air. How can I keep the identity for the lifetime of the application? I wanted something like Thread.CurrentPrincipal but the phone platform doesn’t let you access it.
There was a class, TokenCache, that was part of the original Silverlight project. This sounded useful. it turns out it’s Get/Add wrapper for a Dictionary<>. It’s almost useful, but I want to be able to access this cache at any time. A singleton sort of solves the problem, so lets try that. I added this within the TokenCache class:
public static TokenCache Cache
if (_cache != null)
_cache = new TokenCache();
private static TokenCache _cache;
private static object _sync = new object();
now I can theoretically get access to the tokens at any time, but I want to make the access part of the base Application object. I created a static class called ApplicationExtensions:
public static class ApplicationExtensions
public static IClaimsPrincipal
GetPrincipal(this Application app, string appliesTo)
throw new ArgumentException("Token cannot be found to generate principal.");
public static RequestSecurityTokenResponse
GetPrincipalToken(this Application app, string appliesTo)
public static void
SetPrincipal(this Application app, RequestSecurityTokenResponse rstr)
It adds three extension methods to the base Application object. Now it’s sort of like Thread.CurrentPrincipal.
How does this work? When the RSTR is returned I can call:
Accessing the identity is two-part.
If I just want to get the identity and it’s claims I can call:
var principal = Application.Current.GetPrincipal("https://troymcclure/webapplication3/");
IClaimsIdentity ident = principal.Identity as IClaimsIdentity;
If I want to reuse the token as part of web service call I can get the token via:
var token = Application.Current.GetPrincipalToken(https://troymcclure/webapplication3/);
There is still quite a lot to do in order for this to be production ready code, but it does a pretty good job of solving all the problems I had with domain authentication on the Windows Phone 7 platform.