{{ !articles[0].partner.isSponsoringArticle ? "Platinum" : "Portal" }} Partner
dotnet,mobile,how-to,tools,visual studio,.net & windows,c-sharp,azure

Windows Azure Mobile Services "Rent a Home" Sample, Part 3: Authentication

Last time around, we explored the user interface and the server script for our apartment listings application. Today we'll see how to add authentication to the mix, and limit certain operations only to authenticated users. This is particularly important in the Rent a Home application, because you don't want anonymous users deleting and updating apartment listings! In fact, you'd probably want only the user that created an apartment listing to have the right to update or delete it.

NOTE: Windows Azure Mobile Services is configured by default to enable any user with the application URL and application key to perform create, retrieve, update, and delete operations on any tables belonging to that service. Because the application key is distributed to client devices, this is obviously a very bad idea for a production app -- anyone can extract the application key from your application and perform arbitrary modifications of your data. Therefore, in a production configuration, it is extremely important that you limit access to your data only to authenticated users. You might find it reasonable to allow read data to anyone with the application key, but create/update/delete operations should require authentication.

Windows Azure Mobile Services currently supports authentication with four authentication providers: Microsoft Account (Live Connect), Google, Twitter, and Facebook. (The Rent a Home application supports only Twitter authentication, but it would be trivial to add support for the other providers as well.)

Before you can authenticate with Twitter, you have to create a Twitter application (do so by visitingdev.twitter.com) and specify its consumer key and consumer secret in the Windows Azure portal. Then, you can immediately start making authentication requests from the supported clients:


  new UserAuthenticationCallback() {
    public void onCompleted(MobileServiceUser user,
                            Exception exception,
                            ServiceFilterResponse response) {
      if (exception != null) {
      } else {
        setTitle("Welcome! User id: " + user.getUserId());

NOTE: The user id is not the user name; it is an opaque number that users will be surprised to see. Later in this post, we'll see how to obtain the user's name from the user id.


UIViewController *vc =
  [self.client loginViewControllerWithProvider:@"twitter"
               completion:^(MSUser *user, NSError *error) {
    if (error) {
      NSLog(@"Authentication Error: %@", error);
      //error.code == -1503 means user cancelled the dialog
    } else {
      //Authentication was successful, use self.client.currentUser
      //to read information about the user
    [self dismissViewControllerAnimated:YES completion:nil];
[self presentViewController:vc animated:YES completion:nil];

Windows Phone and Windows 8

var user = await App.MobileService.LoginAsync(
btnLogin.Visibility = Visibility.Collapsed;
txtLogin.Visibility = Visibility.Visible;
txtLogin.Text = "Logged in using Twitter";

Server-Side Authentication
With this client-side infrastructure in place, every subsequent request performed by an authenticated user will be associated with that user, and available to table scripts as the user parameter of the respective script function. Having it available is not enough, however -- we need to explicitly associate our apartment listings with users. The following part of the insert script on the apartment illustrates how easy this is:

function insert(item, user, request) {
  if (user) {
    item.user = user.userId;
  //The rest of the code omitted for brevity

Thanks to dynamic schema, there's no need to pre-declare the user property on apartment listings. This property is actually enough to protect apartment listings from modification by the "wrong" user. For example, this could be our delete script on the apartment table:

function delete(item, user, request) {
  if (!user || user.userId !== item.userId) {
    request.respond(403, 'Only the user that created the ' +
                         'apartment listing may delete it.');

As you saw in the application UI, it would also be valuable to display owner information to other users (this would form the basis of helping users contact the apartment owner to broker a deal). Because the user id is not a human-readable username, we have to use a service-specific API (in this case, Twitter's) to retrieve the username. This is done in the insert script of the apartment table, like so:

item.username = '<Unknown User>';
var identities = user ? user.getIdentities() : null;
if (identities && identities.twitter) {
  var id = user.userId.substring(userId.indexOf(':') + 1);
  var url = 'https://api.twitter.com/1/users/show.json?user_id='
            + id;
  reqModule(url, function (err, resp, body) {
    if (err || resp.statusCode !== 200) {
      request.respond(500, body);
    } else {
      try {
        item.username = JSON.parse(body).name;
        //Continue processing as usual
      } catch (ex) {
        request.respond(500, ex);

Reading the specific user's data depends on the identity provider -- the API endpoint for Twitter users is obviously different from the API endpoint for Facebook users. Carlos Figuera has taken the time to provide a set of code snippets you can integrate in your backend to obtain user information from any of the four identity providers that are currently supported.

At this point, we have added authentication support to our application. Users can sign in with Twitter and their apartment listings are associated with their Twitter identity. We also restricted access so that only authenticated users can create new apartment listings, and only the creating user is allowed to update or delete an apartment listing. One additional thing that would be "nice to have" is support for a custom identity, i.e. custom username and password credentials for your service. Josh Twist of the Mobile Services team explains what would be necessary to provide such support on your application's side.

Finally, there's one fairly annoying detail about the current implementation: it requires the user to sign in every time they open the application. Although the backend doesn't require re-authentication, the client SDK does not currently have an automatic way to persist the authentication token in some secure storage. This shouldn't stop you, however, from persisting the authentication token yourself, and passing it to the appropriate login method of the Mobile Service client. For a complete example, see Josh Twist's post.

In the next installment, we'll take a look at how to configure push notifications on all four platforms, and how to deliver push notifications to registered clients.

I am posting short links and updates on Twitter as well as on this blog. You can follow me: @goldshtn

Published at DZone with permission of {{ articles[0].authors[0].realName }}, DZone MVB. (source)

Opinions expressed by DZone contributors are their own.

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks