Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cordova app using angular & ADAL

I'm building my first mobile app using Cordova. The back-end services live on Azure so I'm trying to get authentication working by using the ADAL plugin for Cordova.

First of all I found out that the library does not do intercepts as the ADAL library for Angular does. I'm using Angular within my Cordova app, paired with material design directives for the look-and-feel. Would have been nice to have interception, but as I understood it's just not there at the moment (should find out how hard it is to implement).

So instead I now wrote a service which will take care of sending REST api requests to Azure, including the correct authentication token. It's based on the sample found here.

This is what I came up with:

var request = function(url)
{
    createContext()
        .then(function () {
            getAuthToken().then(
                function(token) {
                    sendRequest(token, url);
            })
        },
        function (err) {
            $log.error("Failed to create a context.");
        });
};

First it will create the authentication context:

function createContext () {
    return $q(function (resolve, reject) {
        var authenticationContext = Microsoft.ADAL.AuthenticationContext;

        authenticationContext.createAsync(authority)
            .then(function (context) {
                authContext = context;
                $log.log("Created authentication context for authority URL: " + context.authority);
                resolve();
            }, function (err) {
                $log.error("Failed to create authentication context: " + pre(err))
                reject();
            });
    });
};

The using the context it should get the authentication token:

function getAuthToken()
{
    if (authContext == null) {
        $log.error('Authentication context isn\'t created yet. Create context first');
        return;
    }

    return $q(function (resolve, reject) {
        authContext.acquireTokenAsync(resourceUrl, appId, redirectUrl)
            .then(function (authResult) {
                resolve(authResult.accessToken);
            }, function (err) {
                $log.error("Failed to acquire token: " + pre(err));
                reject();
            });
    });
}

And afterwards it should send the request but I'll leave that part out since it never gets there anyway. I feel the need to re-emphasize that I'm a complete n00b at this stuff, so please be easy on me and especially on the code. There's probably a lot of room for improvement, I get that.

When I actually run this, it pops up a window where I need to login using my Microsoft account, cool. I even got two factor authentication first time I tried this, very nice! So I log in and I get returned to the code. But now the authresult variable has a status of "Failed" and there's no access token in the result. Unfortunately there's also no indication of what went wrong. So first part of the question is; what could have gone wrong here?

Now we get to the second part of the question; how do you properly debug these kinds of things? On my desktop I'd run Fiddler to check out the communication, but I don't know how to do that for Android. I'm debugging on my device btw, cause for some reason all of the emulators available to me are extremely slow (VS and Google) even though my hardware specs should support them just fine.

Thanks for any pointers!

Update 03-02-2016

Fiddling around with the code a bit, I decided to pack things in a login function which gives a somewhat shorter sample:

var createContext = function () {
    if (authContext == null) {
        authContext = new Microsoft.ADAL.AuthenticationContext(authority);
    }
};

var getAuthToken = function () {
    if (authContext == null) {
        $log.error('Authentication context isn\'t created yet. Create context first');
        return;
    }

    return $q(function (resolve, reject) {
        authContext.acquireTokenAsync(endpointUrl, appId, redirectUrl)
            .then(function (authResult) {
                resolve(authResult.accessToken);
            }, function (err) {
                $log.error("Failed to acquire token: " + pre(err));
                reject();
            });
    });
}

var login = function () {
    createContext();
    getAuthToken();
}

This code runs on the following input vars:

var authority = 'https://login.windows.net/[tenantid]';
var resourceUrl = 'https://graph.windows.net/';
var appId = '1ef41b17-0943-4359-bc12-014f4fd2d841';
var redirectUrl = 'http://MyApp';

I now used chrome://inspect to see what is going over the wire. And to my big surprise, I see a valid SAML token returned from Azure. It has got my name in it and everything, which I'd recon they wouldn't send after a failed authentication. So it seems that even though the response is ok, the ADAL library doesn't give me a proper response (Status = Failed). Again no clue on how to proceed :S

like image 862
Jasper Avatar asked Jan 29 '16 07:01

Jasper


People also ask

How to create and build angular project in Cordova?

Create and Build Angular Project Create Angular Project, outside the folder of the Cordova project. 2. Go to angular.json , change the outputPath to ../AngularCordova/www Basically, we are giving the build output path to www/ of the Cordova Project.

What is Cordova and why should I use it?

A simple example of a cross-platform app using Cordova and Angular What is Cordova and why use it? Cordova is a cross-platform tool used to develop a Hybrid App. Hybrid apps using Cordova are web apps written using HTML, CSS, and any JavaScript framework/library.

Should I use Angular or typescript for Cordova?

I feel that Angular and TypeScript are very good choices. Because Cordova apps are built and deployed on a mobile device, certain things become more difficult. For instance, live-reload doesn't work like you'd expect it to in a browser. You also have to do some additional things to make sure that TypeScript debugging works, along with sourcemaps.

How do I test a Cordova application?

This is achieved by adding a plugin called Cordova-plugin-device. In order to add this plugin, open terminal (or command prompt) in the directory of your project, and issue the following command: You could test the application in a browser.


1 Answers

I just solved it. And like one would expect, the remedy is as simple as they get. Configuring the application in Azure AD, I chose the "web application" type application, since this is a web application with Angular and all. Now I guess since Cordova translates things to native code, that's not the correct option to chose. As soon as I created a new application as "native application" instead and used the client ID of that one, everything started working.... Sincerely hope this will help someone else in the future...!

like image 137
Jasper Avatar answered Oct 15 '22 20:10

Jasper