Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticate against an Azure Mobile Service App with ADAL.js acquired token

I'm trying to authenticate a HTML app against an Azure Mobile Service app.

The Setup

Both apps use AAD as authentication backend, so both apps have an application registered in the Active Directory:

Azure Mobile Service app:

  • configured as described in https://azure.microsoft.com/en-gb/documentation/articles/mobile-services-how-to-register-active-directory-authentication/
  • I edited the manifest to enable the client flow
  • Enable "single sign-on and read users profiles" under "permissions to other applications" for "Windows Azure Active Directory"

HTML app:

  • in "permissions to other applications" i added the Azure Mobile Service app with the delegated permission "access"

The Azure Mobile Service uses a .NET backend, where i included and configured the NuGet Package "Microsoft Azure Mobile Services .NET Backend Security Extension" as described in https://azure.microsoft.com/en-gb/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users/

The HTML app uses ADAL.JS and Angular:

adalAuthenticationServiceProvider.init(
{
    // Config to specify endpoints and similar for your app
    clientId: "<html app aad client id>",
    redirectUri: "<html app redirect uri>",
    endpoints: {
        '<AMS app client id>': 'https://ampapp.azure-mobile.net/'
    }
},
$httpProvider
);

This setup works as expected, i open my html app, authenticate against Azure AD, get a redirect to my App and I'm logged in. Also, when i try to access my Azure Mobile Service i see that Adal.js injects the bearer token.

The Problem

The bearer token is not accepted by the Azure Mobile Service - i get a 401 not authorized. I don't know why, but the Azure Mobile Service uses it's own authentication header - but ok.

MSDN defines a so called "Client-directed login operation" for the Azure Mobile Service:

"Requests an authentication token from Microsoft Azure Mobile Services by using an identity token already obtained from an identity provider." (https://msdn.microsoft.com/en-us/library/azure/jj710106.aspx)

Ok, so lets do this:

 // obtain token for Azure Mobile Service from Adal.js
 var token = this.getAADToken(ZUMOAuthenticationProvider.Config().url);

 $http({
        method: 'POST',
        url: ZUMOAuthenticationProvider.Config().url + 'login/aad', 
        data: JSON.stringify({
                  "access_token" : token 
              }),
        headers: {
                 'X-ZUMO-APPLICATION': '<application key>'
       }).
       success(function (data, status, headers, config) {
            alert(data);
       }).
       error(function (data, status, headers, config) {
            alert(data);
       }); 

Note: The token acquired by the first line is really a the access token for the azure mobile service aad application and not for the HTML app.

This POST request also gets a 401 response. So i don't know how to authenticate my app. I also tried the azure mobile service js lib. This lib works, but it uses a popup for authentication, but i don't like to add another library to my projects for just a few REST calls.

Similar Problems

When trying to solve my problems i found other Stackoverflow post:

Why isn't my Azure Mobile Service accepting the bearer token ADAL.js is sending it?

  • same problem, no solution (even in the chatlog linked in the last comment)

How do I secure an Azure Mobile Service with Azure AD? ADAL.JS

  • same author as above, i checked everything mentioned in the accepted answer but it doesn't work

I also took a look at the new Azure Mobile apps from the new Azure Management portal but it seems that they are using the same authentication mechanism.

So, how can i get this working?

like image 812
Sven Lauterbach Avatar asked Jun 04 '15 11:06

Sven Lauterbach


People also ask

How do I authenticate Azure App Service?

In the Azure portal menu, select Resource groups, or search for and select Resource groups from any page. In Resource groups, find and select your resource group. In Overview, select your app's management page. On your app's left menu, select Authentication, and then click Add identity provider.

What is Azure Active Directory authentication library Adal?

Microsoft Azure Active Directory Authentication Library (ADAL) is a tool in the . NET framework that lets client applications developers authenticate users to an on-premises Active Directory deployment or to the cloud. ADAL will then secure API calls by locating tokens for access.

What method does Microsoft Azure app Service use to obtain credentials?

Azure App Service provides built-in authentication and authorization capabilities (sometimes referred to as "Easy Auth"), so you can sign in users and access data by writing minimal or no code in your web app, RESTful API, and mobile back end, and also Azure Functions.


1 Answers

Ok, i found my bug:

endpoints: {
    '<AMS app client id>': 'https://ampapp.azure-mobile.net/'
}

This should be

endpoints: {
    'https://ampapp.azure-mobile.net/': '<AMS app id uri>': 
}

After this it works! I'm goind to publish a Angular modul to github which injects the token in the X-Auth-User header to every request like adal.js does.

Edit:

As promised here a more detailed answer:

As mentioned in my question you have to setup 2 applications in Azure Active Directory:

  • an AAD app for the Azure Mobile Service
    • just follow the instructions from this article
  • an AAD app for the HTML app
    • set the "oauth2AllowImplicitFlow" to "true"
    • under "permissions to other applications" add the Azure Mobile Service AAD app enter image description here

Configure the Angular app to use the Azure Mobile Service as an endpoint

adalAuthenticationServiceProvider.init(
{
    clientId:"54110492-4ae3-4c9f-9530-3101458d43fb",
    redirectUri: "https://localhost:44304/",
    endpoints: {
        'https://zumodemoapp.azure-mobile.net/': 'https://zumodemoapp.azure-mobile.net/login/aad'
    }
},
$httpProvider
);

Now you can use the Client-directed login operation to get a Azure Mobile Service authentication token.

var zumoAppID = 'https://zumodemoapp.azure-mobile.net/login/aad';
var zumoLoginUri = 'https://zumodemoapp.azure-mobile.net/login/aad';
var zumoTodoController = 'https://zumodemoapp.azure-mobile.net/tables/TodoItem';

// 1. acquire a oath token for our zumo app from azure ad via adal.js
adalAuthenticationService.acquireToken(zumoAppID).then(function (data) {
     //2. we have the azure ad token, lets get a azure mobile service token
     $http.post(zumoLoginUri,
                JSON.stringify({
                    "access_token": data
                })).
                success(function (data, status, headers, config) {
                    //3. with the azure mobile service token we can authenticate our request
                    $http.get(zumoTodoController,
                                          {
                                              headers:  {
                                                      'X-ZUMO-AUTH': data.authenticationToken
                                              }
                                          }).
                                          success(function (data, status, headers, config) {
                                              alert(data); //yay!
                                          });
                }).
                error(function (data, status, headers, config) {
                    alert(data);
                });
});

As mentioned in the comment I created a more detailed blog post here. If you need more information please leave a comment :).

like image 141
Sven Lauterbach Avatar answered Oct 11 '22 08:10

Sven Lauterbach