I\'m trying to authenticate a HTML app against an Azure Mobile Service app.
Both apps use AAD as authentication backend, so both apps have an app
You can use the AzureMobileServices client script to do a login with an already obtained token:
You need to include the follwing script: https://ajax.aspnetcdn.com/ajax/mobileservices/MobileServices.Web-1.2.8.min.js
Then after you obtained the token with ADAL.JS you can use it to login and obtain a Mobile Service Authentication Token:
var appUrl = 'https://foobar.azure-mobile.net'
, appKey = 'zumo key' // found on the dashboard of the mobile service
, client = new WindowsAzure.MobileServiceClient(appUrl, appKey);
// ...
var token = this.getAADToken(ZUMOAuthenticationProvider.Config().url);
client
.login('aad', { 'access_token': token })
.then(function() {
// client.currentUser.mobileServiceAuthenticationToken
});
This token then needs to be included in succeeding mobile service API requests:
var config = {
headers: {
'X-ZUMO-AUTH': client.currentUser.mobileServiceAuthenticationToken
}
}
$http
.get(appUrl + '/some/path', config)
.then(function (r) {
console.log(r);
});
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:
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 :).
The POST likely returns a 401 because the audience of the AAD token is incorrect. The Mobile Service expects this to be its /login/aad endpoint, but I suspect the token you are sending is actually scoped to the web site you are calling from. The delegated access permission just says that you can take a token from the site and transform it to a token for the Mobile Service. It does not change the nature of the issued token itself.
So the best suggestion is to make sure you are signing into the Mobile Service audience, or perform the delegated access flow. Unfortunately, there don't seem to be too many samples on the latter unless using ADAL.NET
One workaround would be to set the MS_AadAudience app setting on the mobile service to match that of your web site. You should only do this if the site and Mobile Service exist within the same logical security boundary for your application. That is, anything which can sign into your site can access the Mobile Service at this point. Overall, the better approach is to obtain an access token to the mobile service.