Category Archives: Windows 8

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.

Did ya hear the one about the serial killer?

Turns out his victim was found floating in a tub full of corn flakes and milk. Bahhh, dahhh, dahhh, da.

Anyway, in this case it was more that the serializer got killed…by an uncoöperative class. (BTW, that’s not an umlaut over the second “o”. It’s a diaeresis. Lovely sounding term. More on the subject: http://www.newyorker.com/online/blogs/culture/2012/04/the-curse-of-the-diaeresis.html). Typically, this happens because the class has a constructor with parameters. I couldn’t get around that. Well, I don’t want to anyway. I also didn’t want to depart from my vanilla JSON serializer, although in the past I’ve found SilverlightSerializer to be a solution when all else fails…like serializing an entire model. (Why would you want to do that? Long story, for some other time).

The solution is to simply mark up the class with the DataContract attribute and use DataMember for each of the members you want to serialize. In my case, this had the advantage of not serializing a voluminous sub-list I don’t want included. And it allows this class to be used in several places, rather than creating a separate Dictionary or similar.

[DataContract]
public class Exercise
{
 public List<Asset> AssetsList;

public Exercise(int id, int order, string description)
 {
 Id = id;

Order = order;

Description = description;

AssetsList = new List<Asset>();
 }

[DataMember]
 public int Id { get; set; }

[DataMember]
 public int Order { get; set; }

[DataMember]
 public string Description { get; set; }
}

And, voila, we end up with something that can be saved to IsolatedStorage:

[{“Description”:”JUMPING JACKS”,”Id”:0,”Order”:0},{“Description”:”WALL SIT”,”Id”:1,”Order”:1},{“Description”:”PUSH UPS”,”Id”:2,”Order”:2},{“Description”:”CRUNCHES”,”Id”:3,”Order”:3},{“Description”:”STEP UPS”,”Id”:4,”Order”:4},{“Description”:”SQUATS”,”Id”:5,”Order”:5},{“Description”:”TRICEPS DIP”,”Id”:6,”Order”:6},{“Description”:”PLANK”,”Id”:7,”Order”:7},{“Description”:”HIGH KNEES”,”Id”:8,”Order”:8},{“Description”:”LUNGES”,”Id”:9,”Order”:9},{“Description”:”PUSH UP & ROTATE”,”Id”:10,”Order”:10},{“Description”:”SIDE PLANK”,”Id”:11,”Order”:11}]

Kinda like Regex

So I’ve got this auto-incrementing C# TimeSpan that I need to format to just show single minutes and seconds, e.g. 3:48.

var timeSpan = new TimeSpan(0, 0, 0, secondsElapsed++);

Bugger took a while to figure out because I kept trying things like “m:ss” in my string formatter, not catching on that, just as in a Regex expression, I need to escape the colon. That can be done either by:

var timeStr = String.Format("{0:m\:ss}", timeSpan);

or:

var timeStr1 = String.Format(@"{0:m:ss}", timeSpan);

I find that things like this take longer to figure out not because I don’t know how to do them, but because I have these preconceived notions of how they’re supposed to be done. Ordinarily, a string formatter is very forgiving of input so I expected it to “just work” in a certain way.

On another note, displaying a timer looks much better if you use a mono-spaced font. Otherwise, the number jump around as they change. Since this is being used in a Windows Phone app, I set the text block like this:

<TextBlock Name="TBlockTimerDisplay" TextAlignment="Right" FontSize="36" FontFamily="Segoe UI Mono"/>

THere are a couple other typefaces, such as Courier New, included with Windows Phone, but Segoe UI Mono would be my first choice, since it matches the default typeface for the OS.

What’s In Your Wallet?

UPDATE: Use http://openidtest.uninett.no/jwt instead. The Google link below is okay, but I really get annoyed with all the web traffic that occurs every time you hit any page belonging to Google. And, in this case, every time you test a token. Fiddler just clogs up with a ton of web sessions. Openidtest uses javascript within the page. And it works with any browser I’ve tried.

https://developers.google.com/commerce/wallet/digital/docs/jwtdecoder – for those times when you want to see what’s in your wallet…or…er…just decode a JWT (JSON Web Token)…any JWT…without having to wire up something for testing. For instance, I just threw a brand new blank Windows Phone 8 project into a solution. So far I’d only added a Live Sign In button and wanted to verify that the same UID is being generated from there as is from a Windows 8 app. I have a JWT decoder in my server-side code but still need to wire it up to the WP8 client. The server is expecting more info than just a JWT. You have to appreciate when major competitors – unwittingly or not – work together to help the little guy, yeah?

BTW, if you do sign in with the same Microsoft Account, the UID will be the same. Some more on JWTs related to that subject in an upcoming post.

UPDATE: The decoder doesn’t validate that the JWT is actually signed. This brings up an important point: JWTs are not encrypted. They are signed, but all that means is that the data hasn’t been altered in transit. If you’re going to work with JWTs then SSL is a must…or if you couldn’t (for whatever unfathomable reason) use SSL, some sort of public/private key encryption from client to server.

WinRT Raw Notifications and Suspended State

Something to note if your WinRT app uses raw notifications. They will be received by the device but not by the app if it is suspended. This makes sense but may not be obvious sometimes because swiping the left side of the screen may still show the app on the stack. So it will appear to still be active, even if not in the foreground. The exception, of course, is if your app is registered to use a background service and the user has decided your app is important enough to be one of the “Lucky Seven” (those apps given permission to use the Lock Screen). I wouldn’t count on it.

It took me a bit to spot this behavior. I was noticing an instance of the app on one machine would sometimes receive raw notifications if it wasn’t in the foreground, sometimes not. The “not” occurred after a decent time lapse, which was the first clue. My server notification logs were no help because only client devices that were off or logged out of would return a status other than OK from the notification service. As mentioned, if the device is on and logged into, the notification service will successfully send the message. This makes sense. All it cares about is reaching the client at the specified URI. It’s up to the client to do what it wants with the received message. In this case, it appears the WinRT designers elected not to wake up an inactive app. Not a problem, but something to be aware of.

In my case, raw notifications are used to tell the app to update its data. It just means that the same sort of behavior also has to be triggered by resuming from a suspended state. BTW, for those who don’t know, you can suspend an app from within Visual Studio while debugging. To enable this, select TOOLS > Customize from the Visual Studio menu. Check the box next to “Debug Location”. If you have a solution with multiple projects you may have to select the right WinRT project from the Process pull-down menu.

Nobody Notified Me About This!

Earlier on in the Windows 8 development cycle, apps had a checkbox in their app manifest indicating whether the app should be capable of receiving notifications. Later, that explicit requirement went away from the UI in the app manifest window. Thanks to a discussion with a Microsoft DPE (Development & Platform Evangelism) guy yesterday, I was steered towards using a version of the server-side notifications code that includes full diagnostics. My notifications were being sent, but had a “dropped” status, indicating they weren’t making it to the client app. The client app was running. So why, why, why wasn’t it working?

It was then that a little searching online turned up recommendations to check if the app had permissions enabled to receive notifications. Opening the XML for package.appxmanifest (by right-clicking on it and selecting “View Code” or select the file and hit F7), I was able to just add ToastCapable=”true” to the VisualElements tag. That took care of it.

Switching Between Remote Machines when Debugging

I’m currently switching between debugging on an ARM-based Surface RT and another remote machine (actually a VM running Windows 8 on my dev box). I wish there was a more convenient way to switch between remote machines, i.e. from the pulldown menu in Visual Studio. But at least there is a way. Open the project’s properties and select the Debug tab. You can then choose the remote machine. Using the Find button will show all the visible machines:

choosing_remote_machine

Somehow not covered in the documentation

You know that observation Admiral Grace Hopper made?

“Life was simple before World War II. After that, we had systems.”

I think one of the things not often taught to programmers or covered in books is how obscure things can get when systems go interoperable. I was having a hard time getting the sign-on, sign-off behavior promised in the Microsoft Live SDK to work. One thing you do when logging in is pass whatever scopes you need, such as access to SkyDrive or Hotmail. It turns out that whenever you first do this, Live saves a profile for the app, including all the scopes (which the user has consented to). Later, when the hapless programmer is vainly trying various combinations of scopes, unbeknownst to him or her it doesn’t matter because Live doesn’t update the profile.

I happened to come across a post on the MSDN site mentioning that what you have to do is visit https://consent.live.com and remove those scopes (or to be on the safe side, the entire app) from whatever logins you’ve used for testing, e.g:

consent_live

Then the next time you login from an app, the current scopes will be used. The one scope to avoid, at least with the button control for Windows Phone, is wl.signin. One I know to keep is wl.offline_access, which helps avoid having to login every time.

Windows 8/Windows Phone 8 and Xbox Music

I’m one of those people, despite always appreciating the lack of degradation in digital music formats, mourn the demise of vinyl and large-format album art. It even took me a long time to go from the tangibility of owning physical CDs to purchasing my music in the form of MP3 downloads. Other than briefly dealing with hated iTunes for Windows I’ve gotten everything via Amazon. And, until recently, I still at least wanted to “own” my own copies. I never went in for any music subscription or streaming service.

One new feature of Windows 8 is unlimited music via Xbox music. I tried it out just to try it and found a couple of reasons to keep using it. The first is that while the feature is billed as being for Windows 8 users, the same music shows up a little later on my Windows Phone. The second is that it’s free (while still legal). That combination has overridden any objections I had.

UPDATE: I discovered I’d signed up for an introductory offer to XBox music or Live, or whatever. As soon as I cancelled all the music became unplayable. No surprise and not a big deal. I just don’t care right now about having oodles of music. No time to wade through it.

Surface – Initial Impressions

I’m typing this while sitting in SeaTac waiting for my flight back to Helena…on what else but the Surface? This is the 32 Gb version with the Touch Cover given out to developers attending the 2012 BUILD conference in Redmond. Typing on the Touch Cover isn’t as nice as a full regular desktop keyboard. Yet it’s passable, much better than onscreen typing and almost as good as most of the laptops I’ve ever used. That you can easily (and comfortably) rest it on your lap (using the built-in kickstand) is nothing short of fantastic. Keyboard shortcuts, such as CTRL-C, also work – overcoming the chief limitation of Surface, which is the Desktop interface. (More on that below).

The hardware is top-notch. I find the screen just as pleasant to view as the Retina display on the iPad 3. I’m picky about displays too. The keyboard just snaps into place (every time). The kickstand and overall build quality are solid but not heavy. Battery life is really good, although I haven’t done much video playback yet. Little things like the tiny white light on the end of the charger cable are nice touches. Also, having a USB port allowed me to keep my phone charged through long days of sessions and bus travel between Redmond and Fremont in NW Seattle.

The OS is generally good – more so in the “Metro” side. Some apps are a bit rough and a couple crashed on occasion. Yet it took no time at all to get the hang of the gestures that control the UI. The Desktop side is another story. Elements, such as the close button, are too small for touch. Changing a file name almost requires a prehensile tail using touch. The Desktop interface is clearly meant to be used with a keyboard and mouse. And that’s not as bad as it sounds. I see very few iPads without a cover or keyboard and none of those are as good as this one. One of those flexy-sexy Microsoft touch mice is next on my list to buy. I might even get a pressure-sensitive stylus.

Reading Kindle books is a bit odd at first because I prefer portrait mode. The aspect ratio of the Surface makes it feel like you’re reading a brochure. But it is easier to hold than the iPad. I wouldn’t say that the Surface is for everyone. But anyone using Windows will be able to get a lot out of it. And while the competition is hardly going to stand still I can tell you from what I saw and heard at BUILD this OS and ecosystem will only get better…and in some big, impressive and useful ways. Microsoft is hitting it hard on mobile services in particular. The development tools keep getting better too.