Authentication after switching to App Services Mobile App: uid vs sid

I was migrating an Azure Mobile Services form to a new mobile apps app and I am using the new AMS 2.0.0 beta on the client side.

I have two providers (currently) for OAuth 2.0: Google and Twitter.

Previously, I managed to get the provider token through a claim mostly on the server, and there will be a uid (unique id) request that will be either "Google: 123456789" or "Twitter: 123456789010" (or whatever many alphanumeric characters you like). I believe MobileServiceClient.UserId exposed this as well.

Now, after I switched to a new mobile apps app (and now I use the preview portal which is pretty intimidating for the most part) there is no longer a uid requirement, but rather a single sid (session id), something like: "sid: ABCDEFGHIJKLMNOPQRSTUVWXYZ", no matter which provider I log in with. When I looked client side at the MobileServiceClient.UserId value, it also gives this "sid" value.

The fact is that earlier the uid token could uniquely identify the user. Now it is the same for all users of all providers!

How can I get a vendor token with the App Services mobile app that I previously could get from Azure Mobile Services?

Also, can someone point me to the source code for Azure Mobile Services 2.0.0-beta? Is it open source? I cannot find it on GitHub.

Edit: here is a screenshot of the user on the server side: enter image description here

+3


source to share


1 answer


Ok, after re-reading the migration documentation at one time, I was revisiting one of my earlier steps and found it to have an invalid assumption. The documentation mentions considerations for authentication, including the following block of code:

ServiceUser user = (ServiceUser) this.User;

FacebookCredentials creds = (await user.GetIdentitiesAsync()).OfType< FacebookCredentials >().FirstOrDefault();

string mobileServicesUserId = creds.Provider + ":" + creds.UserId;

      

Now I couldn't find "GetIdentitiesAsync" and the ServiceUser has an enumeration property Identities, so I was going with that. (This was, after all, providing very similar information, such as a preview of the ServiceUser.) However, this method seems to receive more data than is already present in the Identities enumeration.

I still can't find it GetIdentitiesAsync

, but after some searching in the browser for the class, I managed to find a singular version of the extension method GetIdentityAsync

in Microsoft.Azure.Mobile.Server.AppService.ServiceUserExtensions

(it's the only method out there). I traced this back to the namespace Microsoft.Azure.Mobile.Server.AppService

, added a using statement and tried the following code:

var hmm2 = await serviceUser.GetIdentityAsync<GoogleCredentials>();

      

I am leaving the variable named "hmm2" because I have the following screenshot:



debug inspection of serviceUser.GetIdentityAsync

The green square on the right with numbers is the unique identifier that I received before migration! Thus, to get the uid, you will need to call this extension method for all provider credentials. When non-null credentials are found, it can use the claim nameidentifier

to obtain a unique provider ID for the user.

I hope that when App Services is ready for production, we have a slightly more concise way to retrieve unnecessary vendor credentials, but for now it works!

Edit: Here is my code now, which works server side (MobileServiceClient.UserId client side doesn't work. You need to return information from server):

var serviceUser = (Microsoft.Azure.Mobile.Server.Security.ServiceUser)Thread.CurrentPrincipal;

try
{
    var googleCreds = await serviceUser.GetIdentityAsync<GoogleCredentials>();
    if (googleCreds != null && googleCreds.Claims != null)
    {
        _CurrentProvider = "Google";
        var nameClaim = googleCreds.Claims.Single(x => x.Key.Contains("nameidentifier"));
        _CurrentProviderKey = nameClaim.Value;
        return;
    }

    var twitterCreds = await serviceUser.GetIdentityAsync<TwitterCredentials>();
    if (twitterCreds != null && twitterCreds.Claims != null)
    {
        _CurrentProvider = "Twitter";
        var nameClaim = twitterCreds.Claims.Single(x => x.Key.Contains("nameidentifier"));
        _CurrentProviderKey = nameClaim.Value;
        return;
    }

    throw new NotSupportedException("The OAuth Provider is not supported.");
}
catch (Exception ex)
{
    throw new InvalidOperationException("There was an error updating the authentication provider. InnerException: " + ex, ex);
}

      

+5


source







All Articles