Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC AD Azure Refresh Token via ADAL JavaScript Ajax and KnockoutJs

There is an inherent design flaw in the type of MVC application I have built and I believe I'm not the first to realize.

I have an MVC 4 Application that utilises AD Azure Authentication that was introduced to the application in the following way

Developing ASP.NET Apps with Azure Active Directory

Once as User is Authenticated and Home.cshtml loads, KnockoutJs is used to perform JavaScript AJAX POST and GET requests to read and write data.

So not exactly a Single Page App, but rather, a mix of traditional postbacks for Authentication and Serving Assets and Read/Write operations through AJAX.

During AJAX requests, the authentication token expires and AD is not able to refresh the token through JavaScript.

The following browser error is observed

XMLHttpRequest cannot load https://login.windows.net/xxx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'xxx' is therefore not allowed access.

I have researched adal.js and the following posts but not sure if adal.js is the solution to my type of application or how best to incorporate it to make it work with my type of application.

My understanding so far:

I am not using AngularJS.

I do not start out authenticating via JavaScript and I my authentication is not JavaScript driven to be able to benefit from adal.js.

Authentication is done server-side and the subsequent OAuth2 refresh token mechanism requires full page postbacks.

I've stumbled on various releated posts by Vittorio Bertocci but none address the particularities of this type of MVC application design.

ADAL, Windows Azure AD and Multi-Resource Refresh Tokens

WAAD doesn't refresh access token from javascript

Combining ADAL.Net and ADAL.js

AngularJS + ADAL.JS set Resource ID (Audience)

like image 251
puri Avatar asked Sep 06 '15 22:09

puri


1 Answers

The issue with your setup is that you are using cookies for authenticating AJAX calls. Cookies aren't really well suited for that, and the limits of the approach typically emerge when you need to make calls outside of your domain and/or when the cookie expires. The fact that it is a common approach, largely as an evolutionary step due to the fact that proper SPA support for auth wasn't available for some time, does not make it a good approach. You are free to stick with your current approach, but that will cause some pain. There is no established mechanism for triggering a session cookie renew from JS. Although that can be hacked together, we don't have samples for that - mostly because it's a hack :) the basic case seems easy enough, but as soon as you start considering all possible cases (what happens if while your app session expired, the user signed out of Azure AD and signed in with a different account?). The most foolproof approach would be to abandon the hybrid approach. If you want to be a JS app, you can eliminate all the server-driven login do so and still retain the ability of doing server side flows (via onbehalf of grants, like https://github.com/AzureADSamples/WebAPI-OnBehalfOf-DotNet). You don;t even need to convert to angular if you don't want to, see https://github.com/AzureADSamples/SinglePageApp-jQuery-DotNet. And if you want to be a postback based app, you can drop the JS part (though that sounds painful).

TL;DR: securing AJAX calls via cookies is not a clean solution and you are bound to feel some pain. Your choices are between patching the issues with ad hoc hacks, or refactor toward a more canonical approach. Sorry for the bad news :(

like image 66
vibronet Avatar answered Sep 21 '22 12:09

vibronet