3
votes

What is the best practice in azure mobile services to use different authentication providers (Facebook, Google, Windows e.t.c.) and understand that this three logins belong to the same user.

Out of the box if a user1 choose to use Facebook for authentication on his mobile phone and add some information to the app, and later he (user1) try to login with Google on his tablet, he will not see his information. Because they are two different users with different tokens. And I want to take some additional information from authentication providers (email) and has my own user table which contains email and other profile info shared for user no matter what provider he uses. How could I achieve it?

P.S. I use .NET as a backend and Windows Phone as a client

1

1 Answers

2
votes

There isn't an out-of-the-box solution here. You would probably be best served by using a lookup table which maps a static user ID that you define to different identity provider IDs. Then, everywhere that you take a dependency on the user ID, you would do a lookup to match the current user identity to your static identifier. Your user ID is what gets stored everywhere else in the database.

The important detail here is that a Mobile Services token maps to a single provider identity. If you look at the user ID, it is actually provider:providerID. So we need to obtain two tokens and validate both together in order to associate two IDs.

On the client, you would have to manually prompt the user to link accounts. You would stash the current token in memory during this process, log in with the new provider, then call and API on the backend which does the association.

string existingToken = App.MobileService.CurrentUser.MobileServiceAuthenticationToken;
App.MobileService.Logout(); // allows login with new provider
await App.MobileService.LoginAsync("google");
await App.MobileService.InvokeApiAsync("associateToken", existingToken);

On the server, you need to be able to validate existingToken (the new one being implicitly validated by restricting the API to AuthorizationLevel.User)

Within that API, you can validate the token using:

IServiceTokenHandler handler = this.Request.GetConfiguration().DependencyResolver.GetServiceTokenHandler()
ClaimsPrincipal claimsPrincipal;
bool didValidate = handler.TryValidateLoginToken(existingToken, ConfigurationManager.AppSettings["MS_MasterKey"], claimsPrincipal);

You should probably also look up the user ID in your lookup table to avoid conflicts.

So overall that's a rough sketch of a possible solution. Unfortunately there isn't anything more turnkey.