The last days I’ve been researching some of the new security features in Windows 8. One of the biggest changes in Windows is definitely the fact that you can now login using your Microsoft Account.
I will describe the details how this works in another post, but the net outcome is, that after you logged in using your Microsoft Account, you can access services that are secured using the Microsoft online infrastructure in a single sign-on fashion. And that’s a pretty compelling feature for a number of scenarios.
Windows itself uses the Microsoft backend e.g. to synchronize your Windows and app settings between your various devices. Other built-in apps use Microsoft provided services like Skydrive, contacts or calendar using the same technology.
Of course, you can do the same – e.g. since every Microsoft Account comes with 7 GB of Skydrive storage, you could take advantage of that for document/data roaming. Or you could use the user’s profile to personalize the client app experience.
Another interesting feature is, that you can also integrate your own backend services with Microsoft’s infrastructure to provide the same SSO experience. It’s actually straightforward once you have all the moving parts together ;) Took me a day and a little help from Shelly from the Windows team. Thanks Shelly!
What’ you need to do:
- Register your app in the Windows 8 Dev Portal
- Configure advanced services
- specify a redirect URI
- take note of app ID and secret
- Install the Live SDK
- Create a Windows Store App in Visual Studio
- associate your app in Visual Studio with the store app from the portal
- Add the client side authentication code
private async void SignInButton_Click(object sender, RoutedEventArgs e)
{
var scopes = new string[] { “wl.signin”, “wl.basic” };
var authClient = new LiveAuthClient(_redirectUri);
// try silent logon first
_loginResult = await authClient.InitializeAsync(scopes);
if (_loginResult.Status != LiveConnectSessionStatus.Connected)
{
_loginResult = await authClient.LoginAsync(scopes);
if (_loginResult.Status != LiveConnectSessionStatus.Connected)
{
await new MessageDialog(“Access denied!”).ShowAsync();
return;
}
}
await ShowProfile();
}
The first time this code runs, the user needs to allow the app access to his data. From that point this will be a completely silent process.
Depending on the scopes you request, you now have access to various backend services like Skydrive, contacts ect…(see here). You can use the REST API or the Live SDK to access those services, e.g.:
private async Task ShowProfile()
{
var client = new LiveConnectClient(_loginResult.Session);
var response = await client.GetAsync("me");
MeImage.Source = new BitmapImage(new Uri(
"https://apis.live.net/v5.0/me/picture?access_token=" +
_loginResult.Session.AccessToken));
foreach (var item in response.Result)
{
OutputList.Items.Add(string.Format("{0}: {1}", item.Key, item.Value));
}
}
(Note: an easier way to get to the user profile is to use the UserProfile class in WinRT, but the above code illustrates the concepts)
Another interesting property on the LiveConnectSession is AuthenticationToken. This is a JWT token that you can use to authenticate to your own backend services!
Here’s how it works:
- Send the authentication token to your service using whatever means. In Web API world this would typically be header.
- On the service side, extract the token.
- Call an API at Microsoft to verify the token. The service needs to know the app ID, app secret and redirect URI for that.
- The API returns a stable user ID scoped to your app that you can use to associate the app user with your backend data.
Here’s a demo implementation of that (Web API controller):
public string Get()
{
var authZ = Request.Headers.Authorization;
if (authZ != null)
{
var authClient = new LiveAuthClient(
appId,
appSecret,
redirectUri);
return authClient.GetUserId(authZ.Parameter);
}
return "anonymous";
}
Nice!
Obviously, the above code needs to be wrapped in a message handler with proper [Authorize], Thread.CurrentPrincipal and all that jazz ;) But you get the idea.
In Thinktecture.IdentityModel terms that would be:
authentication.AddMicrosoftAccount(
appId,
appSecret,
redirectUri);
Job done ;)
You can btw do more with those tokens, but I’ll leave that for another post. Also make sure you watch Shelly’s talk from //build for more information.
HTH
Filed under: ASP.NET, IdentityModel, OAuth, WebAPI
