2
votes

I have created a Xamarin.Forms project and a Table API project. Both have been created through the QuickStart menu in Azure Portal.

I have configured an Azure AD in my portal and I can successfully retrieve a token from the AD through my XForms app. But when I try to login to the Table API using the LoginAsync method from the MobileServiceClient, I receive a "You do not have permission to view til directory or page."

I have been looking through the following guides but with no luck.

How to configure your App Service application to use Azure Active Directory login

Add authentication to your Xamarin.Forms app

How to: Work with authentication

I have also look at the following question but didn't find a solution.

Cordova AAD server flow authentication hangs on Android and iOS

I Am thinking that I might be missing some specific authentication on the Table API project?

Here is my code and setups:

PCL PROJECT IN XFORMS

var ar = await authContext.AcquireTokenAsync(Constants.GraphResourceUri, Constants.ClientId, userCredintials);

            JObject payload = new JObject();
            payload["access_token"] = ar.AccessToken;

            var client = new MobileServiceClient(Constants.ApplicationUrl);
            var user = await client.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);

The Constants.ClientID is the ClientId of the Native Client app and not the webserver. If I switch it around I get a 404.

EXAMPLE OF CONTROLLER FROM TABLE API PROJECT

[Authorize]
public class StatisticController : ApiController

TABLE API StartUp.cs CONFIGURATION

public void Configuration(IAppBuilder app)
    {
        app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions());
        ConfigureMobileApp(app);
    }

MOBILE SERVICE AUTH SETUP enter image description here

SINGLE SING-ON AD SETTINGS enter image description here

NATIVE CLIENT APP SETTINGS enter image description here enter image description here

EDIT

I can duplicate the error through PostMan with the following setup: enter image description here

I tried to include a "X-ZUMO-AUTH" header with the value of the access_token but with the same result. Still no permission. I also tried to exclude every header in the POST request but with no changes. Does this mean that POST requests from my mobile app or Postmand is not allowed?

If I manually browse to mysite.azurewebsites.net/.auth/login/aad in a browser, then I can log in with the users from my AD. So it seems that the AD is communicating correctly with the service and vise versa.

FIXED IT

Great thanks to mattchenderson! As he suggests I should change the constant GraphResourceUri to the client id of my service instead of the normal graph api. Along with adding a single instance of the client I can now successfully log in to my service.

1
Edited answer to include new findings. Still same result though.Casper Nybroe
No takers? No one with similar problems?Casper Nybroe

1 Answers

1
votes

POST requests are allowed, and I use Postman all the time for testing.

The most common cause of an issue like this is an audience validation issue. The audience is a property of the AAD token which says for what resource is this token valid. Given the code above, I would expect the audience to be equal to Constants.GraphResourceUri. My guess is that this is actually the graph API, and not your application, and that would cause a validation failure, although I would expect it to happen when you call LoginAsync(). I would suggest trying the web application client ID instead (that's the Client ID from the "MOBILE SERVICE AUTH SETUP" screenshot).

For an easier time debugging, you can take your AAD token to something like http://jwt.io, and that will help you see the token properties. "aud" is expected to the same as the client ID of the application as registered in the portal, and you want the issuer fields to match up as well. Make sure the token is not expired either.

When using the token to access protected APIs, there are two ways to provide it:

  1. Use the token returned as part of LoginAsync() in the X-ZUMO-AUTH header of your request. This will automatically be done by the SDK for table operations using the same MobileServiceClient.
  2. Use the AAD token directly according to the bearer token spec. That is, include it in the Authorization header, with the value "Bearer ", replacing token with your value.

Also, I see in your code that you are creating a new MobileServiceClient for the login operation. This is something we generally discourage, as the login information is attached to the MobileServiceClient object. If you lose a reference to that, you lose the login information (and a few other settings), and they won't be applied to your table operations. The recommendation is to use a single instance that is referenced elsewhere - for example, in Xamarin, a static variable within your shared code.