Windows Domain Authentication on Windows Phone 7

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:

image

Nothing too spectacularly interesting about the process.  In order to use ADFS though, I need the correct endpoint.  In this case I’m using

https://[external.exampledomain.com]/adfs/services/Trust/13/usernamemixed

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:

WSTrustClient _client;

private void button1_Click(object sender, RoutedEventArgs e)
{
    _client = GetWSTrustClient(
https://[...]/adfs/services/Trust/13/usernamemixed,
new UsernameCredentials("username", "password")); var rst = new RequestSecurityToken(WSTrust13Constants.KeyTypes.Bearer) { AppliesTo = new EndpointAddress("[…]") }; _client.IssueCompleted += client_IssueCompleted; _client.IssueAsync(rst); } void client_IssueCompleted(object sender, IssueCompletedEventArgs e) { _client.IssueCompleted -= client_IssueCompleted; if (e.Error != null) throw e.Error; var token = e.Result; button2.IsEnabled = true; } private WSTrustClient
GetWSTrustClient(string stsEndpoint, IRequestCredentials credentials) { var client = new WSTrustClient(new WSTrustBindingUsernameMixed(),
new EndpointAddress(stsEndpoint), credentials); return client; }

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 
= "urn:oasis:names:tc:SAML:1.0:assertion"; 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,
val.Value, CLAIM_VALUE_TYPE)); } } 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
{
    get
    {
        if (_cache != null)
            return _cache;

        lock (_sync)
        {
            _cache = new TokenCache();
        }

        return _cache;
    }
}

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) { if (!TokenCache.Cache.HasTokenInCache(appliesTo)) throw new ArgumentException("Token cannot be found to generate principal."); return TokenHandler.Convert(TokenCache.Cache.GetTokenFromCache(appliesTo)); } public static RequestSecurityTokenResponse
GetPrincipalToken(this Application app, string appliesTo) { return TokenCache.Cache.GetTokenFromCache(appliesTo); } public static void
SetPrincipal(this Application app, RequestSecurityTokenResponse rstr) { TokenCache.Cache.AddTokenToCache(rstr.AppliesTo.ToString(), 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:

Application.Current.SetPrincipal(rstr);
 

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.

Find my Windows Phone 7

For the last month and a half I’ve been playing around with my new Windows Phone 7.  Needless to say, I really like it.  There are a few things that are still a little rough – side-loading application is a good example, but overall I’m really impressed with this platform.  It may be version 7 technically, but realistically its a v1 product.  I say that in a good way though – Microsoft reinvented the product.

Part of this reinvention is a cloud-oriented platform.  Today’s Dilbert cartoon was a perfect tongue-in-cheek explanation of the evolution of computing, and the mobile market makes no exception.  Actually, when you think about it, mobile phones and the cloud go together like peanut butter and chocolate.  If you have to ask, they go together really well.  Also, if you have to ask, are you living under a rock?

This whole cloud/phone comingling is central to the Windows Phone 7, and you can realize the potential immediately.

When you start syncing your phone via the Zune software, you will eventually get to the sync page for the phone.  The first thing I noticed was the link “do more with windows live”.

image

What does that do?

Well, once you have set up your phone with your Live ID, a new application is added to your Windows Live home.  This app is for all devices, and when you click on the above link in Zune, it will take you to the section for the particular phone you are syncing.

image

The first thing that caught my attention was the “Find my Phone” feature.  It brings up a list of actions for when you have lost your phone.

image

Each action is progressively bolder than the previous – and each action is very straightforward.

Map it

If the device is on, use the Location services on the phone to find it and display on a Bing Map.

Ring it

If you have a basic idea of where the phone is and the phone is on, ringing it will make the phone ring with a distinct tone even if you have it set to silent or vibrate.  Use this wisely. Smile

Lock it

Now it gets a little more complicated.  When you lock the phone you are given an option to provide a message on the lock screen:

image

If someone comes across your phone, you can set a message telling them what they can do with it.  Word of advice though: if you leave a phone number, don’t leave your mobile number. Winking smile

Erase it

Finally we have the last option.  The nuclear option if you will.  Once you set the phone to be erased, the next time the phone is turned on and tries to connect to the Live Network, the phone will be wiped and set to factory defaults.

A side effect of wiping your phone is that the next time you set it up and sync with the same Live ID, most settings will remain intact.  You will have to add your email and Facebook accounts, and set all the device settings, but once you sync with Zune, all of your apps will be reinstalled.  Now that is a useful little feature.

Finally

Overall I’m really happy with how the phone turned out.  It’s a strong platform and it’s growing quickly.  The Find my Phone feature is a relatively small thing, but it showcases the potential of a phone/cloud mash up and adds so much value to consumers for when the lose their phone.

In a previous post I talked about the security of the Windows Phone 7.  This post was all about how consumers can quickly mitigate any risks from losing their phone.  For more information on using this phone in the enterprise, check out the Windows Phone 7 Guides for IT Professionals.

Windows Phone 7 Blogger Night

imageEarlier this week Microsoft Canada put on an event for the Windows Phone 7 RTM.  Joey Devilla has an excellent post on the event, but here is my take away.

Beautiful

First off, this interface is amazing.  It is functional, beautiful, and FAST.  Hardware acceleration is a thing of beauty.

Developer Friendly

Developing on competing platforms can be an ugly thing.  There are a number of reasons, all valid, but when it comes right down to it, sometimes the development environment just sucks.  Notsomuch with #wp7dev.  Full Visual Studio and Expression Blend integration is another thing of beauty. 

image

Silverlight development is a joy in these environments.  Oh, and the phone is ALL Silverlight.  How COOL is that?

Start to finish, 10 hours to develop a simple application.  That includes the learning curve of the IDE and Silverlight. 

The Community

Microsoft kind of dropped the ball on 5, 6, 6.1, and 6.5 for the Windows Phone.  The community was openly hostile to this.  Not too many people liked those versions.  With the introduction of 7, the criticality of the community has been high, but they have been extremely open to the possibilities this new UI brings with it.  Microsoft is touting this as a technology reset.  The community tends to agree.  Let’s hope it meets expectations when it hits the stores.

What’s Next?

Get the tools.  Try it out.  Find a local event that has a device and try and break your application.  Chances are, you’ll have more fun than you expect.

downloadTools

Thinking About how we Display Data

Earlier I had discussed how to bring the data from a database to the Windows Phone 7.  Now I’d like to discuss how we think about displaying that data.  It’s important to know the relationships in the data so we can think about how everything should be structured.  We want to create a simple interface that is smooth and logical.  All data is different and this is by no means the “right” way to do it, but it feels right to me.

This is industry standard stuff, and our data is modeled around it.  Each layer would be a collection of each sub-layer.  So as an example There are multiple tracks per breed, and multiple cards per track.  A Card is a set of races for a specific track.  My best understanding is that we try very hard to stick to one Card per day. 

For this application though we aren’t going to assume anything.

image

It seems logical to me that we should mimic this structure in the logic, so lets try and shoot for that.  This is not the finished version, but of a mock-up of what we might/should see.

Initial Page:

image

Once the breed has been selected we move onto selecting the track:

image

And so on…

In the future I will discuss the breakdown of each page and how the data is actually displayed, plus how we switch between pages.

Getting the Data to the Phone

A few posts back I started talking about what it would take to create a new application for the new Windows Phone 7.  I’m not a fan of learning from trivial applications that don’t touch on the same technologies that I would be using in the real world, so I thought I would build a real application that someone can use.

Since this application uses a well known dataset I kind of get lucky because I already have my database schema, which is in a reasonably well designed way.  My first step is to get it to the Phone, so I will use WCF Data Services and an Entity Model.  I created the model and just imported the necessary tables.  I called this model RaceInfoModel.edmx.  The entities name is RaceInfoEntities  This is ridiculously simple to do.

The following step is to expose the model to the outside world through an XML format in a Data Service.  I created a WCF Data Service and made a few config changes:

using System.Data.Services;
using System.Data.Services.Common;
using System;

namespace RaceInfoDataService
{
    public class RaceInfo : DataService
{ public static void InitializeService(DataServiceConfiguration config) { if (config
== null) throw new ArgumentNullException("config"); config.UseVerboseErrors
= true; config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); //config.SetEntitySetPageSize("*",
25); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
} } }

This too is reasonably simple.  Since it’s a web service, I can hit it from a web browser and I get a list of available datasets:

image

This isn’t a complete list of available items, just a subset.

At this point I can package everything up and stick it on a web server.  It could technically be ready for production if you were satisfied with not having any Access Control’s on reading the data.  In this case, lets say for arguments sake that I was able to convince the powers that be that everyone should be able to access it.  There isn’t anything confidential in the data, and we provide the data in other services anyway, so all is well.  Actually, that’s kind of how I would prefer it anyway.  Give me Data or Give me Death!

Now we create the Phone project.  You need to install the latest build of the dev tools, and you can get that here http://developer.windowsphone.com/windows-phone-7/.  Install it.  Then create the project.  You should see:

image

The next step is to make the Phone application actually able to use the data.  Here it gets tricky.  Or really, here it gets stupid.  (It better he fixed by RTM or else *shakes fist*)

For some reason, the Visual Studio 2010 Phone 7 project type doesn’t allow you to automatically import services.  You have to generate the service class manually.  It’s not that big a deal since my service won’t be changing all that much, but nevertheless it’s still a pain to regenerate it manually every time a change comes down the pipeline.  To generate the necessary class run this at a command prompt:

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
DataSvcutil.exe
     /uri:http://localhost:60141/RaceInfo.svc/
     /DataServiceCollection
     /Version:2.0
     /out:"PATH.TO.PROJECT\RaceInfoService.cs"

(Formatted to fit my site layout)

Include that file in the project and compile.

UPDATE: My bad, I had already installed the reference, so this won’t compile for most people.  The Windows Phone 7 runtime doesn’t have the System.Data namespace available that we need.  Therefore we need to install them…  They are still in development, so here is the CTP build http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=b251b247-70ca-4887-bab6-dccdec192f8d.

You should now have a compile-able project with service references that looks something like:

image

We have just connected our phone application to our database!  All told, it took me 10 minutes to do this.  Next up we start playing with the data.

MIX 10 – First Impressions

Once of the interesting elements of this year’s MIX is the complete domination of Twitter as a medium for distributing updates. If you have been following me on Twitter (I’m @LACanuck), then you will already have heard a lot about the Windows Phone 7 development announcements. However, as useful as Twitter is, it’s not really a place for opinion. Unless your opinions fit into <140 characters. Mine don’t

Windows Phone

There is no question that there is a lot of buzz around developing apps for the Windows Phone 7. This is completely understandable, as WP7 allows Silverlight developers the ability to create applications for the phone. According to Scott Gu’s keynote, there is only “one Silverlight”. That is to say that applications that run on the browser should also be able to run on WP7.

Now there is going to be a little bit of a reality check for that statement, especially as we hit Silverlight 4. I’m not sure, for example, if Silverlight as running on WP7 has the concept of a trusted application. I suspect that it doesn’t, although I’m open to correction if my assumption is misplaced.

But working solely within the security sandbox is not the only real difference. Specifically, the design of a WP7 application is very different than a Web application. The size of the design surface is, naturally, much smaller on the WP7. And the UI needs to consider that main UI gesture is touching, a paradigm that doesn’t apply to Web applications. All of this is to say that while, theoretically, the same application could run on both platforms, it’s much more likely that different views will be used by the different targets. If nothing else screams that you should be using MVVM as a design pattern for Silverlight, this will.

Deployment

Once you see what’s possible in the WP7 environment, the excitement regarding creating applications is easy to understand. And not only are the apps exciting, so too is the ability to monetize your application. Microsoft will be making a Marketplace available so that you can sell your apps on-line. Given how well Microsoft has done with community driven marketplaces, I have no doubt this will be successful.

But what about your own personal applications? What if you want to develop a WP7 application that is used by your mobile sales force? At the moment, the answer seems to be that you’re out of luck. This might change before it goes live, but the word that I’m hearing is that the only way to get apps onto your phone is through the Marketplace.

Now, that’s not completely accurate. If you have Visual Studio 2010, you can deploy your application to a physically connected phone. However, the time to live for applications which have been deployed in such a matter is limited, To, approximately, a month. After which the app would need to be redeployed.

I’m not a fan of this. In fact, in my mind ,it drops the collection of Silverlight developers who might write WP7 apps by 50%. At least. I can take guesses at the reason why this limitation is the case, but still, it’s not what I was hoping for. The term for what I’m looking for is ‘siloed’ deployment’ (that is, deployment only for people in a particular silo) and I’m hoping that it becomes part of the released version of WP7 before it goes live with the first version.

While there is more of interest that is being revealed here, this is probably a decent start. And I’ll be both blogging and tweeting as much as I can while I’m here at MIX ‘10