Enabling Single Sign-On for Windows 8 Azure Mobile Apps
One of the common complaints about the authentication support in the Windows 8 SDK for Azure Mobile Services is that regardless of whether the user selects the “save password” / “remember me” checkbox when entering their credentials, every time the application starts and the user needs to authenticate, they have to enter their credentials all over again. Currently the only way to enable the single sign-on (SSO) for Win8 apps would be to use the Live SDK (or some native SDK from the other providers, such as Facebook or Google) and then only authenticate with Azure Mobile Services with the token received from that SDK.
We recently released an update of the Azure Mobile Services client SDK for Windows 8 (along with an update to the service runtime), and this feature is now available. To enable single sign-on, we need to use a new overload to the LoginAsync (or login from the JavaScript client), and we also need to set the package SID of the Windows 8 application from the store. Let’s see how I can change my application to use this new feature. This is my current app. It currently uses Facebook authentication (a simple app which gets data from the graph API about the logged in user), but if I were using the other three authentication providers the steps to enable SSO would be the same.
The code for the application (in one method) is the following:
- private async void btnGetData_Click_1(object sender, RoutedEventArgs e)
- {
- try
- {
- var user = await MobileService.LoginAsync(MobileServiceAuthenticationProvider.Facebook);
- AddToDebug("Logged in as {0}", user.UserId);
- var table = MobileService.GetTable("UserIdentity");
- var item = new JsonObject();
- await table.InsertAsync(item);
- AddToDebug("Item: {0}", item.Stringify());
- var fbAccessCode = item["identities"].GetObject()["facebook"].GetObject()["accessToken"].GetString();
- var httpClient = new HttpClient();
- var resp = await httpClient.GetAsync("https://graph.facebook.com/me?access_token=" + fbAccessCode);
- var body = await resp.Content.ReadAsStringAsync();
- JsonObject bodyJson = JsonObject.Parse(body);
- foreach (var key in bodyJson.Keys)
- {
- AddToDebug("{0}: {1}", key, bodyJson[key].Stringify());
- }
- }
- catch (Exception ex)
- {
- AddToDebug("Error: {0}", ex);
- }
- }
First, the change in the client, which is the simple one: just use the new overload of the LoginAsync method – see the change below. Everything else remains exactly the same.
- var user = await MobileService.LoginAsync(MobileServiceAuthenticationProvider.Facebook, true);
- AddToDebug("Logged in as {0}", user.UserId);
- var table = MobileService.GetTable("UserIdentity");
Now, for the required server change. To enable this feature, we actually need to have a package id for the application in the Windows 8 store. If you still haven’t created an application on the Windows Store, you can follow the instructions in the tutorial for enabling push notifications. So far I hadn’t needed to do that, although once my app was ready for publishing to the store I’d had to do that anyway. So let me create one now:
After the application is created (I’ll call mine “blogpost20130204”) we can associate the VS project with the application in the store:
Next, we need to find the package SID for the store application. I actually find the dashboard for the Live Connect Developer Center easier to navigate than the Windows Store dashboard, so I’ll go from there:
After selecting the application, select “Edit Settings” and “API Settings” and it should show the package SID for my app:
Now that we have that value, we need to set it on the Azure Mobile Service portal for our application. Currently the only place where we can set it is on the “PUSH” tab, so that’s where we go, even through we’ll use it for authentication, and not push (in the future I’m sure there will be an update to the portal and that will be in its proper place).
Ok, now we have both the client and the server changes made. And that should be it. The username / password information should be now remembered by the client application!
More info / known issues
The old behavior and the new behavior are a byproduct of our usage of the Web Authentication Browser control in our Windows 8 SDK. Over the next couple of days I’ll publish a post with the internal details of our authentication, and how it relates to that control.
There’s currently one issue that we’re aware of: if you try to use both the Live SDK to authenticate the user to the app (a.k.a. client-side auth flow) and the single sign-on for Microsoft accounts (a.k.a. server-side auth flow), then the server-side flow won’t work. Notice that this isn’t something that one would normally do, as both do the same thing. Just something to be aware.
Comments
- Anonymous
March 20, 2013
This causes an exception for me when using a Microsoft account for login. Is it not supported? - Anonymous
March 21, 2013
We currently have a problem with using this type of SSO (with the additional parameter) and microsoft accounts, which we're looking into fixing in the coming months. At the moment, the best way to do SSO with microsoft accounts is to use the Live SDK as described at www.windowsazure.com/.../single-sign-on-windows-8-dotnet. - Anonymous
June 17, 2013
I'm trying to use the LoginWithMicrosoftAccountAsync method on WP8 with the saved token from the last successful login, but the method always fails with "MobileServiceInvalidOperationException: Error: The authentication token's signature was malformed or signed by a different key." Any suggestions? - Anonymous
July 02, 2013
Tony, which token are you passing to that method? The LoginWithMicrosoftAccountAsync takes the authenticationToken returned by the Live SDK login operation. - Anonymous
March 16, 2014
I'm trying to do SSO from both Windows Phone 8 and Windows 8.1 to the same Mobile Services instance. The Live SDK won't let me have 2 apps with the same redirect url (i.e. the mobile services redirect url) and following the method outlined here (registering the Windows Store package SID and calling LoginAsync) results in a 'Connecting To a Service' prompt with the error message 'Microsoft account is experiencing technical problems. Please try again later.'). Any info on this? I've posted in the Live Connect forums.