5
votes

I get two different SID for the same user when the user is logging in through a Azure Web App (ASP.NET MVC) and Xamarin.iOS app

Setup

Azure WebApp ASP.NET 5 with API Controllers

Xamarin iOS App with Microsoft.WindowsAzure.Mobile.Client SDK Azure B2C AAD

User on Web

I get the ObjectIdentifier value that is the AAD SID:

var userClaim = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

User on Mobile

I get only a Nameidentifier value and no ObjectIdentifier

ClaimsPrincipal mobileUser = this.User as ClaimsPrincipal;
var mobileUserClaim = mobileUser.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier");

The SID is completely different, the SID for the user authenticate from Mobile get SID:xxxx while from Web gets xxx

I know if I setup one Azure Mobile App and one Azure Web App the SID is the same when authenticating. But I dont want to manage two sites for the size (small) of my App. The purpose of the App is to have a Simple Web App to perform some actions and the same actions on the Phone, from the Phone I use the Azure Mobile Service SDK and InvokeAPIAsync to use the API controller in the Web App.

Thanks

2

2 Answers

1
votes

I want to clarify the situation. You are observing two SIDs:

1) From AAD, by logging into AAD via web browser.

2) From Azure App Service (Web App and Mobile App), likely from using LoginAsync from our client. This method would invoke the server-directed login flow.

This is by design. MobileServiceClient gets App Service tokens, and authenticates with your Mobile App with that token. You can exchange the auth token you get from Azure App Service for the AAD SID by making a GET to the .auth/me endpoint.

After your client is authenticated with App Service and AAD, you can get more information about the AAD user (or whatever identity provider) by calling yoursite.azurewebsites.net/.auth/me, and parsing the response for the claim you want:

({"typ" : "http://schemas.microsoft.com/identity/claims/objectidentifier").

Another strategy would be to use ADAL (http://www.nuget.org/packages/Microsoft.IdentityModel.Clients.ActiveDirectory/) from your client app to login with AAD, and then use the AAD access token to get a Mobile App token using the appropriate LoginAsync overload:

https://github.com/Azure/azure-mobile-apps-net-client/blob/master/src/Microsoft.WindowsAzure.MobileServices.iOS/Extensions/MobileServiceClientExtensions.cs#L55

The parameters you add should be in format {"access_token":"[AAD access_token value]"}

Brett Samblanet's wiki on the .NET Server about User IDs should help understand what is going on: https://github.com/Azure/azure-mobile-apps-net-server/wiki/Understanding-User-Ids

0
votes

I finally got it to work:

string authority = "https://login.windows.net/[TentantId].onmicrosoft.com/";
            string resourceId = "[myApiClientId]";
            string clientId = "[clientId]";
            string redirectUri = "https://[URL]/.auth/login/done";

            AuthenticationContext ac = new AuthenticationContext(authority);
            AuthenticationResult ar = await ac.AcquireTokenAsync(resourceId, clientId,
                new Uri(redirectUri), new PlatformParameters(this));
            JObject payload = new JObject();
            payload["access_token"] = ar.AccessToken;

            string authHeader = ar.CreateAuthorizationHeader();
            HttpClient client = new HttpClient();
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "[API URL Route]");
            request.Headers.TryAddWithoutValidation("Authorization", authHeader);
            HttpResponseMessage response = await client.SendAsync(request);
            string content = await response.Content.ReadAsStringAsync();