Monthly Archives: January 2014

Using Microsoft Live for Authentication with Windows 8.x and Windows Phone 8 Apps

If you’re the impatient type and are just looking for a code sample, check out https://github.com/stonetip/authTest. I would also appreciate any comments or suggestions to make the code better. The solution contains a Web API service and Windows 8/Windows Phone apps.

I first started looking into this because I needed a way to authenticate users and didn’t want to build or maintain such a system. Additionally, people are used to being able to use social media accounts, which reduces resistance to trying out something new. For the time being, since my apps are for these two platforms I’ve chosen to focus on using just Live authentication. A good part of that is the user experience with more comprehensive approaches wasn’t very satisfactory. A significant design goal is to re-use as much code as possible across Windows 8 and Windows Phone.

Performing authentication and using to securely connect to a service involves some significant steps and pieces:

1)      Registering Client Apps and Services with the Windows Store and Microsoft Live

2)      Setting up a Service

3)      Assembling the right combination of code to authenticate properly and at the right times.

4)      Using the Live SDK and a JWT (JSON Web Token) decoding and verification library

Furthermore, there are certain design goals that need to be met:

1)      Avoid having user log in as much as possible…preferably only once.

2)      Maintain security, both locally and on the server

3)      Make the experience as seamless as can be

4)      Re-use as much code as possible across Windows 8 and Windows Phone

Like many things, it was overwhelming at first to see how the pieces of the puzzle fit together. This is complicated somewhat by differences in the way Windows 8 and Windows Phone handle signing in and staying signed in/authenticated. As you may know, Windows 8 operates on the principal of SSO (single sign on) with Microsoft accounts. Applications don’t have their own interface for signing in. All the user will see upon installing the application is a one-time pop-up asking for permission to use whatever scopes the app has requested. All you have to do is include wl.signin in your sign-in scopes.

 image001  image002
Windows 8 Windows Phone

Note: See below on how to reset this after you’ve tested it with an account

Windows Phone, on the other hand, doesn’t use SSO. Fortunately the Live SDK handles this as long as you, again, remember to include wl.offline_access. Then the only difference is that you have to sign in (via a browser pop-up in the app) to your Microsoft account one time.

Note: If you’ve looked at Live SDK samples for Windows Phone they include a sign-in button (or at least used to when I first investigated them). It’s not necessary to use. The code included in this post and in the accompanying download will demonstrate that.

So how does the authentication process work anyway?

It’s important to have an overview of the process. The application needs to be able to authenticate itself with the server. This is handled by communicating with Live (when necessary), which returns a JWT (JSON Web Token). The JWT is then passed to the server with every call (yes, that’s right) as an Authorization header. The server validates the JWT and if it passes returns the requested data.

image003

At no time are user credentials or client secrets stored within the client. This is critical because no matter what steps you take to obfuscate code there’s no guarantee the app won’t be compromised.

What’s a JWT and what does it contain?

A JSON Web Token is a string containing three parts – a header, a claims section, and a signature. The first two are JSON strings, e.g  {“typ”:”JWT”,  “alg”:”HS256″}, which are base-64 encoded. The signature is hashed using – and this is important – the client secret Live generates for your app (more on this in a moment). It is also encoded, then all three parts are concatenated, separated with a period, such as:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cm46bWljcm9zb2Z0OmFwcHVyaSI6ImFwcGlkOi8vMDAwMDAwMDBYWFhYWFhYWCIsInZlciI6MSwidWlkIjoieHl6MTIzIiwiaXNzIjoidXJuOndpbmRvd3M6bGl2ZWlkIiwiZXhwIjoxMzkxMTA2MjQ5LCJ1cm46bWljcm9zb2Z0OmFwcGlkIjoiMDAwMDAwMDBYWFhYWFhYWCIsImF1ZCI6Im15c2l0ZS5henVyZXdlYnNpdGVzLm5ldCIsInR5cCI6IkpXVCJ9.56c3v2DvM-XzC5tbKgcJWXsPYwV13ZJZPdqS-TxuGrM

This particular example would be decoded as:

Header

{

    “alg”: “HS256”,

    “typ”: “JWT”

}

Claims

{

“urn:microsoft:appuri”: “appid://00000000XXXXXXXX”,

“urn:microsoft:appid”: “00000000XXXXXXXX”,

“uid”: “xyz123”,

“iss”: “urn:windows:liveid”,

“exp”: 1391106249,

“ver”: 1,

“typ”: “JWT”,

“aud”: “mysite.azurewebsites.net”

}

Signature (encoded)

56c3v2DvM-XzC5tbKgcJWXsPYwV13ZJZPdqS-TxuGrM

The items that are important as far as server validation is concerned are the issuer and audience. Also of importance is the expiration UTC date/time, which is expressed in Unix epoch seconds. This is covered more in the Sample section.

One thing you should understand about JWTs is that they are not encrypted. Only the signature is. So if not debugging traffic, strongly consider using HTTPS. If you need to authenticate a user, whatever traffic you’re sending probably needs to be encrypted anyway.

Note: uid (user id) is a unique user id specific to the app (as registered with Live). In other words, the uid will be the same for both a Windows 8 app and a Windows Phone app using the same app registration. And it will be the same across multiple devices. Another id source, of course, is the user’s id from_liveClient.GetAsync(“me”). However, if you’re going to use an ID, say stored in a remote DB, the app-specific one would be better. If the data is ever compromised, it would be harder for someone to use against other Live-based apps or services linked to the user.

A couple web-based pages where you can view a decoded JWT are http://openidtest.uninett.no/jwt and https://developers.google.com/wallet/digital/docs/jwtdecoder. The latter looks a little funky in IE but it works. The Federation Lab page will also encode a JWT, but neither one will actually validate the signature.

Registering an Application

I’ve found that it easiest to first associate a Windows Store app from within Visual Studio. Right-click on the project, select Store> Associate App with the Store… to do this. Once it’s done, under the Dashboard on the developer site (https://appdev.microsoft.com/StorePortals/en-us/Home/Index), find the app and click on its Edit link. Select Services. You’ll see a link to navigate to Live Services, e.g. “If you have an existing WNS solution or need to update your current client secret, visit the Live Services site.”

From there, you’ll see the “If your app uses Live Connect services, review:” heading and can use the Authenticating link to get your Client secret (which should only be used server side because you should be just sending a valid JWT).

image006

Copy the Client secret to Notepad or similar so you will have it available to place in the web.config of the Web API service. Then use the Representing your app link to fill in the details on the app, such as the redirect URI:

image008

The Redirect URI will be the LiveCredential used in your Windows 8 app. So make a note to have that available.

Note: Generally, you’ll want to restrict JWT issuing unless you have more than one store app that uses the same backend service. Don’t worry, this doesn’t affect also using a Windows Phone app.

If you are using the service with a Windows Phone app, you will also need to visit https://dev.live.com and select your app from My Apps, then API Settings and enable Mobile client app. This page is also where you will find your Client ID. Not to be confused with the Client secret, this is a value you will use for the LiveCredential in a Windows Phone app. (Incidentally, if you compare the MainPage.xaml.cs files in my Win8/WP8 projects you’ll see that this is the only difference aside from a few usings).

The App and Service Samples

I’ve provided two barebones apps for Windows 8 and Windows Phone, along with a Web API service. What they demonstrate is a way to stay signed into an app securely, pass a JWT to the server along with a POST, validate the JWT and return data. Live JWTs are issued with a 24-hour expiration. So even though your client app may not require logging in more than once, this means the app still needs to keep track of the latest expiration time and request a new token if needed. Otherwise the server will refuse to return data if it can’t validate the token.

The way I prefer to handle this is to have the server extract the expiration when it receives the JWT and return that to the client in the response headers. My samples don’t store the expiration in IsolatedStorage nor do anything to examine it under various usage scenarios, other than when launching. In any production code, you’d want to be sure to incorporate whatever’s needed to ensure a smooth, error-free experience for your users.

I spent a fair amount of time looking into the server-side code and decided to use the System.IdentityModel.Tokens.JwtSecurityTokenHandler for validation. I’d tried another library and fed it a token with a purposely altered signature, which it didn’t reject. They may have fixed it since, but I know this one works. All requests are routed through a handler set up in Global.asax.cs. Configuration settings unique to the app registration and server are stored in Web.config, e.g:

<add key=”AllowedAudience” value=”mysite.azurewebsites.net” />

<add key=”ClientSecret” value=”[APP CLIENT SECRET]” />

<add key=”Issuer” value=”urn:windows:liveid” />

These are placed inside appSettings.

Global.asax.cs will need to have references to System.IdentityModel and System.IdentityModel.Tokens added. Under the Application_Start method, add:

ConfigureTokenValidation(GlobalConfiguration.Configuration);

Note: Once this is implemented, along with the code below, the service will only work with valid JWTs. During initial setup, just to see that the service is working, comment this line out. You can enter a URL in a browser, such as http://[MACHINENAME]/AuthTestWebAPI/api/values and should see a JSON test string, e.g. [“value1″,”value2”].

Create a Configure method:

private static void ConfigureTokenValidation(HttpConfiguration config)

{

config.MessageHandlers.Add(new TokenValidationHandler());

}

And here’s the TokenValidationHandler class:

Note that the JWT’s expiration is extracted from the Thread.CurrentPrincipal, which contains all the decoded JWT claims. The expiration is then injected back into the Request, using a custom header. I think this is the first time I’ve ever done this for an internal operation on a server, but hey it works and seems a reasonable enough way to pass the value onto the ValuesController that will return a response to the client. I prefer to leave times in Unix epoch seconds when shuttling them around between server and client rather than transform them to DateTimes. It’s a smaller, less encoded value.

On the client side, it’s important not only to have the expiration to know when to ask for a new JWT, but also to know not to ask. If you had code that kept asking for a new JWT every time the user visits a page, resumes an app or even when first launching, it creates a noticeable delay. In testing, I’ve seen it usually take about 6 seconds to acquire a JWT. So you want to do so only when necessary.

Another configuration step is to set up the AuthTestWebAPI project up for local testing. You can still use the same audience URI (and, in fact, need to). But under Properties > Web I’d recommend setting it up to run on a local IIS server under the machine name. That will allow testing on your local network. I use a Surface tablet and a phone for this. Select Local IIS, provide a URL with your machine name, and click on Create Virtual Directory:

image010

Note: You’ll need to run Visual Studio as Administrator to do this!

And while on the subject of configuration and local testing, in the AuthTestWin8 project, open Package.appxmanifest, navigate to capabilities and be sure to select Private Networks (Client & Server) or you won’t be able to access an intranet URL via the application.

image011

Testing with the Clients

Once the service is configured (including enabling the ConfigureTokenValidation method), try running the client apps. If everything is working, you should see something like this:

image012

Try hitting the Test Server Auth button a couple times. Note that the Time value changes, but not the Expiration. That’s because the expiration time is being compared to the last known expiration time (again, something you’d normally store in IsolatedStorage). This way, an unnecessary call to the Live servers is avoided. You will notice, however, with the Windows Phone app that upon launch the app will always get a new token, while the Win 8 app will not. This is something, again, where I’d use IsolatedStorage to store the token and expiration time and check the last known expiration time to see if a new token is required. If not, the stored token could continue to be passed to the server.

Resetting the Permissions Dialog

Sometimes you want to return to a state where you can mimic the user’s initial installation experience, including seeing the Live Permissions dialog. It may come as a surprise, but uninstalling/reinstalling the app won’t do it. What you need to do is visit https://account.live.com/Permissions, log on under whatever user account you’re using for testing and click on the Manage apps and services link (https://account.live.com/consent/Manage). On that page, look for the app, e.g. AuthTest, click on Edit and remove it. This will allow you to start over again.

Make it Musical

When I first started taking guitar lessons, my instructor told me that while it would be hard at first to sound good (it’s still hard, bro) to “always keep it musical.” What he meant and what I try to explain to my son as he progresses as a guitarist is to make it sound like a song. Don’t get wrapped up in the mechanics or lose the beat.

Yesterday, I was with our other boy and we stopped into Staples to get some school supplies. This was my first opportunity to play around with both an iPad Air and the new Mini, which is the one I’d get if when I start doing cross-platform development for iOS. They are both really nice devices and very light. I had an iPad (3) and the Air blows it away. Yesterday evening toting my Surface to a book seminar I’m part of it felt heavy in comparison.

Yet this was also my first time really experiencing iOS 7. And one thing that struck me is that the animations seemed rather clunky. How could this be? The display tag below it proudly extolled the presence of the mighty A7 processor. It’s not a hardware issue. I was surprised how rough things like the transition between portrait and landscape are. Not to make comparisons too much, but Microsoft did a pretty good job on that in Windows 8.x.

It wasn’t until we were driving home that it struck me what it was. Whoever designed those animations failed to make them musical. I had happened to turn the radio on, which was set to NPR. While I’m not much of a Classical music fan, I appreciate certain composers and pieces. The overture from Verdi’s La Forza del Destino was playing. As it opened, I suddenly pictured in my mind animating tiles and color transitions in time with the music and reflecting the mood of the piece. Feel free to listen to it while you finish reading:

If you’ve ever seen Fantasia or Bruno Bozetto’s parody Allegro Non Troppo then you will have some idea what I am talking about. The next time you make an animation or transition, try setting it to music while you’re working on it. One thing these master composers had down is timing and mood.

In a subsequent post, I’ll show a recent example where I was setting animation and transitions to sound effects for an animated, vector-based splash screen. Ordinarily I wouldn’t add one to an app, preferring to get right down to business, but this is for a game and it’s  also meant to add a little branding and some personality. One thing I found is that visual perception effects the way the user connects sound and sight. Sometimes you have to futz with timing so that a sound either starts earlier or later.