Mango Sample: OAuth2 & Live Id
In June 2011, the Windows Live Developer platform added OAuth2 to seamlessly access Live Id, Hotmail, Calendars SkyDrive, and other Windows Live Assets. There’s a showcase site you should check out.
OAuth2 puts the user in charge of what applications are allowed to access. We have branded this “Windows Live Connect”. It is for web, desktop, and mobile applications. Today, we’ll discuss how to integrate Live Id into your Windows Phone application.
Yes, it’s this simple:
- Register your application http://dev.live.com
- Embed a Web Browser somewhere
- Send the user to the login URL.
- Listen for the browser to navigate to the “redirect_uri”.
- Pull the OAuth token from the redirect URL.
- Use a Web Request object in C#.
- With the token, request the user’s profile.
- Save the resulting JSON data.
- You are done!
Step 1: Create your Application Key
Step 2: Add a Login.xaml page to your application
Create a Login.xaml. Send the user here to log in. You *could* put this on any ole page – but why the clutter, grasshopper? There is only a browser and a progress bar. This won’t be a XAML breakthrough for you. But it will get the job done.
Note: Users login through Windows Live Connect. It’s browser-based. But we fetch profile data using a C# Web Request – we’ll need a Progress Bar.
In my mind, surfacing a browser breaks the Metro UI guideline telling you not to do that. But, it is how Windows Live Connect implements it. Someday we’ll get an SDK.
Ask yourself: Why is the user logging in?
You must decide WHY the user should log in. This is important. The first time that flashlight app asks me to login, I might play along. The second time, it’s an uninstall. That fast. Just implement the correct level of annoyance.
Is it to identify them? If you are just wanting to get the user’s name and profile data, then you might only require the user to log in one time. That could be a good decision.
Is it to authenticate them? If you are wanting to authenticate that the current user is the expected user, then you might implement a timeout or log in @ each launch.
Step 3: Send the User to Login
Remember Windows Live Connect handles the login. All we do is pass the user to their login page. So, we must construct the URL property (passing out Client ID).
MSDN says: The implicit grant flow can be used by both web-based and desktop applications. In this flow, the client makes an authorization request to https://oauth.live.com/authorize/ with request_type=token. This is a standard OAuth 2.0 flow and is defined in full detail in the implicit grant section of the OAuth 2.0 spec.
Login URL: https://oauth.live.com/authorize?client_id=12345&response_type=token&scope=wl.signin%2cwl.basic%2cwl.offline_access&redirect_uri=https%3a%2f%2foauth.live.com%2fdesktop&display=touch
What’s in that Query String?
https://oauth.live.com/authorize is the login page itself. It works properly only when the query string values are correct. In the end, only client_ID is dynamic. You can hard code the rest. But, let’s look a little closer at these items:
- client_id: What’s the user logging into? Your application. Pass your Client ID URL, and Live Connect will validate that ID and tailor the resulting token.
- response_type: “token”. Just hard code it and move on
- scope: The user will specifically authorize your application for certain things. We're asking for: simple authentication (wl.signin), profile name (wl.basic), and access to their profile later (wl.offline_access). These are pretty basic.
- redirect_uri: The user will login and either approve or deny your application access. Either way, where do they go from there? Here, the redirect_Uri. But, your phone app is not a web server – so Live Connect provides a desktop/mobile URL.
- display: Windows Live Connect can optimize the Login page for “touch” screens.
Step 4: Handle the response
After the user approves or denies your application, they are redirected to your redirect_uri. If they approve, there’s a token; if they deny, an error message. Both of are in the URL. There’s no other payload. So, let’s do some string parsing!
First, let’s handle a denied access:
In the code above, see line 2? We’re parsing the query string to a dictionary (with the System.Linq ToDictionary() extension method). Now, we can search for an entry of key “error” – it’s value will be “access_denied”. And, that’s how we detect a denial.
Now, let’s handle an allow access:
In the code above, just like when parsed “error” we’re parsing “access_token”. If you want a nice, robust application (and who has time for that?) you can test that it’s really there and returns not empty when you finally get it. Either way, we have the token. What’s next?
Step 4: Request the Profile
The user is not really involved in this step. They’ve logged in successfully and they have granted our application permission. Granted permission to do what? Permission to perform this next step – request the profile.
To use this JSON, we’re going to need to parse it. But wait, there’s more! Why parse when we can de-serialize? That’s right. Let the Framework do it for you. For this, we’ll need a simple class into which we can de-serialize the JSON. Like this:
In the code above, see [DataContract]? You’ll need System.Runtime.Serialization for that. And see [DataMember]? That attribute’s (Name) constructor let’s us specify what the JSON key is without requiring our class to have the same.
Now, let’s request our JSON payload from the Windows Live Connect service – passing our token. Remember, since the user will still need to wait for this step, this would be the right time to pop up a nice progress bar. Normally, this shouldn’t take long.
In the code above, see line one? We’re building the URL to the /me REST operator. It returns profile data. And, see where we place the request? Calling BeginGetResponse() starts our asynchronous operation. But, my favorite is _Json.ReadObject(). This takes the stream (the JSON) and de-serializes it into our C# class. Presto! We’ve got Profile.
Step 5: Save the Result
One more thing. Now that you have the data, what are you going to do with it? In the sample code, I take the whole profile class and jam it into Isolated Storage. That works just fine – and persists across sessions and even reboots.
Is this the right solution for your application? That’s up to you. You might have a local database. You might use a web service. There’s no reason you can’t take it from where and then simply use the scheme you already have in place.
Integrating an existing authentication scheme into your Windows Phone application just makes sense. Why reinvent? Windows live Connect/OAuth2 gibes your users the familiar Windows Live ID Login and you get their profile data. Have fun!