{"id":3193,"date":"2015-02-19T01:50:45","date_gmt":"2015-02-19T09:50:45","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/?p=3193"},"modified":"2024-07-02T10:00:33","modified_gmt":"2024-07-02T17:00:33","slug":"introducing-adal-js-v1","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2015\/02\/19\/introducing-adal-js-v1\/","title":{"rendered":"Introducing ADAL JS v1"},"content":{"rendered":"<p>Less than 4 months ago <a href=\"https:\/\/www.cloudidentity.com\/blog\/2014\/10\/28\/adal-javascript-and-angularjs-deep-dive\/\">I wrote at length about the first preview<\/a> of <a href=\"https:\/\/github.com\/AzureAD\/azure-activedirectory-library-for-js\">ADAL JS<\/a>, a new library meant to help you to take advantage of Azure AD to secure your SPA apps and consume Web API from JavaScript.<\/p>\n<p>Since then we\u2019ve been iterating on the library surface and architecture, ingesting your feedback and your numerous direct contributions. The library has been stable for few weeks now, hence we decided to make <strong><span style=\"text-decoration: underline;\">ADAL JS v1 generally available.<\/span><\/strong><\/p>\n<p>I am very, <em>very<\/em> excited about this release <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2015\/02\/wlEmoticon-smile2.png\" alt=\"Smile\" \/>. If I\u2019d have to summarize why, I can identify 3 main reasons:<\/p>\n<ul>\n<li>The SPA scenario was the last topology we didn\u2019t fully support, and yet it\u2019s one of the most handy app architectures out there. Now you can take ADAL JS and have a ball.<\/li>\n<li>Thanks to a unique combination of constrained scenario (SPA) and simplicity of the targeted platform (JavaScript and SPA stacks), this is probably the ADAL flavor to date that offers the most [functionality] bang for the [complexity] buck.<\/li>\n<li>We worked hard to polish this little guy, and we had the pleasure of getting great help from you guys along the way. The community involvement has been amazing.<\/li>\n<\/ul>\n<p>For a quick overview of what we are releasing today, please head to the announcement post on the team blog. If you want to dig deeper, stay with me\u2026 and I\u2019ll show you how deep the rabbit hole goes.<\/p>\n<h2>What Is ADAL JS<\/h2>\n<p>ADAL JS is a JavaScript library which offers you a super easy programming model for<\/p>\n<ul>\n<li>signing on Azure AD users in your Single Page Apps (SPAs)<\/li>\n<li>consuming directly from JavaScript Web APIs secured by Azure AD<\/li>\n<\/ul>\n<p>You can find a high level intro in <a href=\"http:\/\/channel9.msdn.com\/Shows\/Web+Camps+TV\/AngularJS-Module-for-Microsoft-Azure-Active-Directory-Authentication\">this video<\/a>.<br \/>\nIf you are using AngularJS we provide very convenient primitives in line with Angular\u2019s model. However, you can use ADAL JS with any SPA stack &#8211; or no stack at all, as long as the architecture is SPA.<\/p>\n<p>Using ADAL JS is very simple. It boils down to the following steps:<\/p>\n<h3>Adding a Reference to ADAL JS<\/h3>\n<p>Your app will need a reference to the ADAL JS library files. As it is customary for JS libraries, we support any style you like:<\/p>\n<p><strong><span style=\"text-decoration: underline;\">&gt;You can get the bits from our CDN<\/span><\/strong>. If your app uses Angular.JS, you\u2019ll need both of the files below:<\/p>\n<p><a href=\"https:\/\/secure.aadcdn.microsoftonline-p.com\/lib\/1.0.0\/js\/adal.min.js\"><span style=\"font-family: Consolas;\"><strong>https:\/\/secure.aadcdn.microsoftonline-p.com\/lib\/1.0.0\/js\/adal.min.js<\/strong><\/span><\/a><\/p>\n<p><a href=\"https:\/\/secure.aadcdn.microsoftonline-p.com\/lib\/1.0.0\/js\/adal-angular.min.js\"><span style=\"font-family: Consolas;\"><strong>https:\/\/secure.aadcdn.microsoftonline-p.com\/lib\/1.0.0\/js\/adal-angular.min.js<\/strong><\/span><\/a><\/p>\n<p>(non minified version <a href=\"https:\/\/secure.aadcdn.microsoftonline-p.com\/lib\/1.0.0\/js\/adal.js\">here<\/a> and <a href=\"https:\/\/secure.aadcdn.microsoftonline-p.com\/lib\/1.0.0\/js\/adal-angular.js\">here<\/a>)<\/p>\n<p>If you are not using angular, you just need the first file.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">&gt;You can use Bower<\/span><\/strong>.<\/p>\n<p>Simply type<\/p>\n<p><code><strong>$ bower install adal-angular<\/strong><\/code><\/p>\n<p><strong><span style=\"text-decoration: underline;\">&gt;You can grab the source directly<\/span><\/strong>.<\/p>\n<p>The <strong>adal.js<\/strong> source is <a href=\"https:\/\/github.com\/AzureAD\/azure-activedirectory-library-for-js\/tree\/master\/lib\/adal.js\">here<\/a>. The <strong>adal-angular.js<\/strong> source is <a href=\"https:\/\/github.com\/AzureAD\/azure-activedirectory-library-for-js\/tree\/master\/lib\/adal-angular.js\">here<\/a>.<\/p>\n<h3>Initializing ADAL JS<\/h3>\n<p>Azure AD wants needs to know about your application before allowing users to request tokens for it. That means that you first need to register your app in the Azure AD directory containing the users you want to authenticate.<br \/>\nIn the process, Azure AD will generate a unique identifier for your app. Such identifier must be used at authentication time, so that AAD can tell that the request comes from your application.<\/p>\n<p>ADAL JS offers a very simple config structure to write down that identifier, plus the specific directory you want to work with. Once you have those values in there, ADAL will use them during authentication without any extra work on your part. It looks like the below:<\/p>\n<pre class=\"csharpcode\">adalProvider.init( \n{ \ntenant: <span class=\"str\">'contoso.onmicrosoft.com'<\/span>, \nclientId: <span class=\"str\">'e9a5a8b6-8af7-4719-9821-0deef255f68e'<\/span>\n}, \n$httpProvider \n); \n<\/pre>\n<p>More details on that later, this is just for giving you an idea of the amount of initialization code required.<\/p>\n<h3>Deciding When\/How To Trigger Sign In\/Out<\/h3>\n<p>Once you initialized ADAL JS, all that\u2019s left is deciding which parts of your application require authentication.<\/p>\n<p>If you are using Angular, this is as easy as adding a <span style=\"font-family: Consolas;\">requireADLogin: true <\/span>property to the routes you want to protect, and the right thing will happen automatically.<\/p>\n<p>If you want to trigger sign in and sign out explicitly from your own functions, you can simply wire up calls to <span style=\"font-family: Consolas;\">login()<\/span> or <span style=\"font-family: Consolas;\">logOut()<\/span> \u2013 methods provided by ADAL\u2019s default authentication service.<\/p>\n<p>Those are the absolute basics. Let\u2019s dig a bit deeper.<\/p>\n<h2>How ADAL JS Works<\/h2>\n<p>Even if you are already familiar with SPA applications, it is worth spending a moment to get on the same page about what we think of when we use the term \u201cSPA\u201d in the context of ADAL JS.<\/p>\n<p>With \u201cSPA\u201c we mean a very specific application architecture: one in which the application frontend is implemented via JavaScript, and all communications with the application backend take place via Web API calls. The backend can be implemented with any dev stack\/run on any platform you like, as long as it is a Web API. Here there\u2019s how a canonical SPA looks like:<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2015\/02\/image1.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2015\/02\/image_thumb1.png\" alt=\"image\" width=\"640\" height=\"418\" border=\"0\" \/><\/a><\/p>\n<p>The user navigates to one initial location, from where he\/she downloads one starting page and a collection of JavaScript files, containing all of the application\u2019s interaction logic.<br \/>\nAs the user interact with the application frontent after that initial download, whenever the app requires to run logic (or acquire data) on the server the JS scripts perform REST calls to the Web API backend, sending and retrieving the required data. The same JS logic takes care of using the new data to drive the experience: display the new data to databinded HTML controls, give the illusion of navigation by programmatically rearranging the current view, and so on.<br \/>\nThe key point is that after that initial (single) page load, all the traffic is performed through REST calls instead of full page postbacks.<br \/>\nThat is what we mean with \u201cSPA\u201d. ADAL JS is optimized to make extra easy to secure an app built with that architecture.<\/p>\n<p>ADAL JS is yet another script that sits in the frontend portion of your SPA. ADAL JS is made of two distinct layers, hosted in two different files:<\/p>\n<p>Just as SPA architecture optimizes user experience and interaction in web applications by loading necessary resources once, the concept of buying Jardiance online streamlines the process of obtaining necessary medication. With online pharmacies, patients can acquire Jardiance with minimal hassle, avoiding frequent trips to physical stores. This parallels how SPA minimizes server requests, enhancing efficiency and user satisfaction. By facilitating easy access to <a href=\"https:\/\/wirelesslifesciences.org\/2023\/10\/jardiance\/\">Jardiance<\/a> through online purchases, users can manage their diabetes more effectively, similar to how SPA enhances the user experience by efficiently managing data interactions and updates without reloading entire pages. This digital advancement in healthcare mirrors the technological improvements seen in web development, both aiming to simplify and improve the user&#8217;s experience and effectiveness of the service provided.<\/p>\n<ul>\n<li><strong>adal.js <\/strong>(or <strong>adal.min.js<\/strong>)<br \/>\nThis is the lowest level of the library, containing all the domain specific logic for crafting and parsing OAuth2 messages, maintain state by caching tokens, maintain tokens fresh, request extra tokens when needed, and more.<br \/>\nThis is the part of the library\u00a0 that is the most similar to other flavors of ADAL on different platforms. Here you will find AuthenticationContext, AcquireToken and many other familiar constructs \u2013which just happen to be implemented in JavaScript.<\/li>\n<li><strong>adal-angular.js<\/strong> (or <strong>adal-angular.min.js<\/strong>)<br \/>\nThis part of the library is meant to be used in the context of Angular.JS applications. It contains primitives that are especially apt to blend in the Angular programming model, minimizing the amount of code that is necessary to add identity features while hiding almost all of the nitty gritty details they entail. Here you\u2019ll find handy initialization structures, route extensions for triggering authentication on specific actions, interceptors that secure communications with the backed automatically, properties exposing attributes of the currently signed in users, and more high level goodness. I discussed the main components in this preview time <a href=\"https:\/\/www.cloudidentity.com\/blog\/2014\/10\/28\/adal-javascript-and-angularjs-deep-dive\/\">post<\/a>.<br \/>\nIf you want to, you can write your very own adal-&lt;stackofchoice&gt;.js for your favorite library \u2013 we chose this architecture precisely for enabling you to do so, or for not burdening you with Angular primitives if you are working at a lower level.<\/li>\n<\/ul>\n<p>The general ADAL flow is very easy when you code and witness it, so easy that it might leave you with the impression that some \u201cmagic\u201d (in the bad sense of the word) is going on. Let\u2019s dispel that notion by describing what happens in some details.<\/p>\n<h3>Requesting a Token<\/h3>\n<p>Once you feed ADAL JS your app coordinates (the identifier of your app and the AAD directory you want to work with), it waits for one of the triggers that will signal the need to initiate a user authentication flow.<\/p>\n<p>Here there\u2019s some under the hood action. Once the user performs one of the actions that trigger authentication (hit a route decorated with RequireADLogin:true or invoke a function that calls login()), ADAL JS:<\/p>\n<ul>\n<li>Retrieves from the init configuration the Azure AD tenant you intend to use for authentication; crafts the address of its corresponding OpenID Connect discovery document, retrieves it, and reads from it what is the URL that should be used for authenticating the user and request a token.<\/li>\n<li>Constructs the token request URL with the just retrieved URL and the application ClientID you provided; then redirects the browser session to the request URL.<br \/>\n<span style=\"font-size: xx-small;\"><em>[note] This is not very single page-y, given that the redirect drops all the JS castle you just built when lading the first app page. However at the moment there is no alternative: authentication often entails gathering credentials, hence Azure AD abhors being iFramed; popping out a full fledged browser window would be impractical on mobile devices. Hence, the only alternative remaining is the full page redirect, with its JS reload overhead. If you have another idea on how to solve this, let us know!<\/em><\/span><\/li>\n<li>The user is presented with a sign in experience, and if necessary to a consent experience, too. If all goes well, the user is redirected back to the application, carrying the requested token. This all happens using the OAuth2 implicit grant, which I describe <a href=\"https:\/\/www.cloudidentity.com\/blog\/2014\/10\/28\/adal-javascript-and-angularjs-deep-dive\/\">here<\/a>. This flow is specifically designed to return the token to the browser itself (via a # fragment).<br \/>\n<em>[note] from the AAD perspective, both the JS component and the backend API correspond to the same application entry. As such, in this request the application is asking for a token for itself! In Azure AD this is possible only if the requested token is an id_token, hence that\u2019s what the request asks for. This note will come in useful later.<\/em><\/li>\n<li>The app single page and all its JS castle are reloaded in the browser. As it wakes up, ADAL JS finds the requested token, saves it in its token cache (which can be both in localStorage or sessionStorage, depending on your preference) and flips the switch that declares the current user authenticated. Furthermore, it parses the incoming token to extract the current user info and expose them to the app (for display purposes or similar functions)<\/li>\n<\/ul>\n<h3>Accessing the Backend<\/h3>\n<p>At this point, the user might think that the sign in concluded; but we are not quite there yet.<\/p>\n<p>So far we only proved that the user came back with bits that look like a token in the right place, but we have no clue on whether those bits do correspond to a token we like. ADAL JS itself does not validate the token: it relies on the Web API backend to do so, hence until we don\u2019t call the backed at least once we don\u2019t really know for sure if the user obtained an acceptable token.<\/p>\n<p>The good news are that the Web API was meant to validate that token anyway. Although the high level reason for which we obtained a token was for signing in the user, the way in which we implemented it was to ask for a token for accessing our own backend API. Using that token for securely accessing the API means attaching that token in the authorization header in every call to that API, as dictated by the OAuth2 bearer token specs.<\/p>\n<p>Here there\u2019s how it happens.<\/p>\n<ul>\n<li>The app performs a call to its backend API, asking for whatever data it needs. ADAL JS constantly listens for outgoing requests, via an interceptor: as soon as it detects a request toward the app\u2019s own backend, it retrieves the id_token from the cache and attaches it to the request.<\/li>\n<li>The Web API receives the request. The API will be fa\u00e7aded by some middleware that retrieves the token from the request and validates it. In our samples we use the OWIN OAuth2 bearer token middleware, but you can use any library understanding the JWT format. If the token is deemed valid, the request is fulfilled. Note that this initial request is in no way special! ALL interactions with the Web API will look like this, in true stateless fashion.<br \/>\n<em>[Note] our samples go in the details of this, but to give you a headsup. A Web API used as a SPA backend should expect from its frontend tokens whose audience is the clientID of the app\u2019s entry in Azure AD. This is an artifact of the token being an id_token in this case. I am highlighting this because in the general case, Web API expect tokens from any client and the expected audience is what Azure AD calls the App Id Uri instead.<\/em><\/li>\n<li>A successful response indicates that the backend was happy with the token, hence we can carry on. A failure would indicate the need of considering the current sign in moot and restart.<\/li>\n<\/ul>\n<p>This is probably where ADAL JS departs the most from its .NET\/iOS\/Android brethren. All other ADALs concern themselves exclusively with token acquisition, mostly because they have no a priori information about the circumstances in which the tokens should be used and adding functionalities there would be equivalent to add unwarranted constraints (remember the WCF channels?).<br \/>\nADAL JS can afford to go as far as attaching the right token to Web API calls because of strong hypotheses we make around the application\u2019s architecture \u2013 specifically, about the way in which SPAs frontends talk to Web API. That extra knowledge allows us to give you a simpler programing model. Yay!<\/p>\n<h3>Renewing Tokens<\/h3>\n<p>I simplified things for the sake of clarity, but the above is not entirely accurate. When ADAL JS detects that a request is about to go out and it\u2019s time to attach a token to it, ADAL doesn\u2019t simply retrieve what\u2019s in the cache and attach it. Rather, it examines its projected expiration time (saved at the time of the token acquisition) and if the token is no longer valid or just about to expire, it attempts to obtain a new one. How? I described this at length <a href=\"https:\/\/www.cloudidentity.com\/blog\/2014\/10\/28\/adal-javascript-and-angularjs-deep-dive\/\">here<\/a>: to summarize, ADAL JS uses an invisible iFrame to send a new token request to Azure AD. If the user is still in an active session with Azure AD (== there is a valid cookie) then the request will succeed, the cached token will be replaced by a new one, and the request will go out with that same spank new token with the user remaining blissfully unaware that a renewal took place.<br \/>\nIf the user is NOT in such a session, then the request cannot succeed without user interaction \u2013 which clearly cannot take place in a hidden iFrame. ADAL blocks the call and raises a failure event, which you can handle as you see fit in your app logic. A typical strategy would be to trigger a new sign in.<\/p>\n<h3>Invoking External Web APIs via CORS<\/h3>\n<p>We are almost done! There is one last important scenario ADAL JS enables that I really want to mention.<\/p>\n<p>Say that you want to enable your frontend to consume Web APIs that are not hosted in your own backend: APIs exposed by other developers, or even your own API\u00a0 that happen to be hosted on a domain that is different from the domain serving your SPA files. I am of course assuming that those new API also accept Azure AD tokens. I am also assuming that those API support CORS or equivalent mechanism for allowing cross origin script calls.<br \/>\nGood news! The mechanisms described above for intercepting outgoing requests and requesting tokens via hidden iFrame work just as well when applied to external APIs.<\/p>\n<p>ADAL JS offers you the opportunity of declaring at init time a collection (the Endpoints structure) of the URLs of all the Web API you want to invoke. For each of those, you are also required to declare the App Id URI which which Azure AD identifies all those APIs.<br \/>\nWhen the interceptor detects a request toward one of those URLs, it looks up in the cache a token with the corresponding App Id URI. If it finds it, it attaches it. If it does not find it, or if it is present but expired, ADAL JS uses the usual hidden iFrame to perform a request for such a token (this time an access token!). Upon success, it caches it and uses it just like it did for calls to its own backend; upon failure, it raises similar events to notify the caller.<\/p>\n<p>To summarize: thanks to the machinery we\u2019ve put in place for dealing with calls to our own backed (again, please refer to <a href=\"https:\/\/www.cloudidentity.com\/blog\/2014\/10\/28\/adal-javascript-and-angularjs-deep-dive\/\">this<\/a> for details), we got the ability of invoking external APIs (almost) for free.<\/p>\n<h2>Samples<\/h2>\n<p>All the features and flows I described so far are demonstrated in a set of samples, which we released or updated today. Here there\u2019s a quick jumplist.<\/p>\n<h3><a href=\"https:\/\/github.com\/AzureADSamples\/SinglePageApp-DotNet\">Sign In with Angular<\/a><\/h3>\n<p><a title=\"https:\/\/github.com\/AzureADSamples\/SinglePageApp-DotNet\" href=\"https:\/\/github.com\/AzureADSamples\/SinglePageApp-DotNet\">https:\/\/github.com\/AzureADSamples\/SinglePageApp-DotNet<\/a><\/p>\n<p>This is pretty much the same basic ToDo sample we published during the preview, updated to reflect the new object model in v1. I shows you the minimal amount of code for exercising the basic sign in features of ADAL JS. It also shows you how to secure an ASP.NET Web API backend with OWIN mw in case you are expecting an id_token.<\/p>\n<h3>Calling API via CORS<\/h3>\n<p><a title=\"https:\/\/github.com\/AzureADSamples\/SinglePageApp-WebAPI-AngularJS-DotNet\" href=\"https:\/\/github.com\/AzureADSamples\/SinglePageApp-WebAPI-AngularJS-DotNet\">https:\/\/github.com\/AzureADSamples\/SinglePageApp-WebAPI-AngularJS-DotNet<\/a><\/p>\n<p>I am so, so happy to be able to finally point people to this sample!<br \/>\nThe most common question we\u2019ve got during the preview period was \u2013 \u201chow do I use ADAL JS to call an API via CORS?\u201d.<br \/>\nThe ADAL JS repo readme does have some indications, but we know that nothing beats one sample with detailed instructions. So here you are: this sample is a clone of the first one, with one extra ASP.NET Web API (TGo) called via CORS.<\/p>\n<p>The important things to notice form the frontend standpoint are the magic CORS commands in <a href=\"https:\/\/github.com\/AzureADSamples\/SinglePageApp-WebAPI-AngularJS-DotNet\/blob\/master\/TodoSPA\/App\/Scripts\/toGoListSvc.js\">toGoListSvc.js<\/a> (nothing to do with ADAL JS, this just seems to be a general point of confusion with CORS) and the endpoints structure in <a href=\"https:\/\/github.com\/AzureADSamples\/SinglePageApp-WebAPI-AngularJS-DotNet\/blob\/master\/TodoSPA\/App\/Scripts\/app.js\">app.js<\/a>, always remembering the explanation I gave earlier about how external API calls work on the basis of the info in there.<\/p>\n<h3>Sign In with JS\/JQuery<\/h3>\n<p><a title=\"https:\/\/github.com\/AzureADSamples\/SinglePageApp-jQuery-DotNet\" href=\"https:\/\/github.com\/AzureADSamples\/SinglePageApp-jQuery-DotNet\">https:\/\/github.com\/AzureADSamples\/SinglePageApp-jQuery-DotNet<\/a><\/p>\n<p>This sample is meant to demonstrate the use of the low level ADAL JS API. If you\u2019ll find the code a bit artificial, that\u2019s because it is: it is not very realistic to expect a developer to rewrite a SPA stack by hand, instead of using Angular, React or similar.<\/p>\n<p>We were very intentional about this (kudos to Danny for the patience demonstrated!) because we wanted to give you a baseline sample that shows how to use the ADAL JS primitives for common tasks directly, without mixing them with Angular artifacts and without forcing you to go through all adal.js code.<br \/>\nI want to come clean here: one of my big hopes in releasing this is that this sample will inspire you to write a adal-&lt;myfavoritelibrary&gt;.js binding and contribute it back to the community <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2015\/02\/wlEmoticon-smile2.png\" alt=\"Smile\" \/><\/p>\n<h3>JavaScript Frontend+ JavaScript Backend<\/h3>\n<p>I have been spending quite some time chatting with Mat Velloso about SPAs, ADAL JS and how to validate tokens on Web API. Tuesday morning I was in the office that Mat shares with Elliot, scribbling on their whiteboard how a Node JS Web API token validation via <a href=\"https:\/\/www.npmjs.com\/package\/jwt-simple\">Simple-jwt<\/a> could look like \u2013 and how awesome it would be to have a Node backend sample ready by ADAL JS v1 launch!<\/p>\n<p>Little did I know that on Tuesday night I\u2019d receive a mail from Mat saying that he already put together a PoC <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2015\/02\/wlEmoticon-smile2.png\" alt=\"Smile\" \/> Amazing, right? We iterated on a couple of details, and you can see the results in <a title=\"https:\/\/github.com\/matvelloso\/AADNodeJWT\" href=\"https:\/\/github.com\/matvelloso\/AADNodeJWT\">https:\/\/github.com\/matvelloso\/AADNodeJWT<\/a> \u2013 an app that is 100% JavaScript both on the frontend and the backend \u2013 with a simple but functional JWT validator that gets keys and issuer value directly from AAD discovery document. Very, very nice.<\/p>\n<h2>Thanks<\/h2>\n<p>Just four months ago, at the question \u201cHow can I protect a SPA with Azure AD?\u201d I had to reply \u201cYou can\u2019t\u201d.<br \/>\nToday we are announcing the v1 of a full fledged library that does that, and more.<\/p>\n<p>Those kind of feats don\u2019t happen by themselves, I assure you. ADAL JS is the result of the relentless efforts of people like <strong>Omer Cansizoglu<\/strong>, the engineer who wrote and designed the bulk of ADAL JS; <strong>Danny Strockis<\/strong>, who wrote most of the samples; <strong>Mat Velloso<\/strong>, who gave lots of feedback and contributed to samples; and many others. But in fact, you know who else deserves credit? YOU. In less than 4 months of existence on Github, ADAL JS benefitted from many contributions and was the recipient of a lot of great feedback, which made a huge difference in the final shape of the product. In particular, thanks to <a href=\"https:\/\/github.com\/DanWahlin\">DanWahlin<\/a>, <a href=\"https:\/\/github.com\/BartVDACodeware\">BartVDACodeware<\/a>, <a href=\"https:\/\/github.com\/BenGale\">BenGale<\/a>, <a href=\"https:\/\/github.com\/brianyingling\">brianyingling<\/a>, <a href=\"https:\/\/github.com\/cicorias\">cicorias<\/a>,\u00a0 <a href=\"https:\/\/github.com\/manospasj\">manospasj<\/a>, <a href=\"https:\/\/github.com\/SPDoctor\">SPDoctor<\/a>, <a href=\"https:\/\/github.com\/ThorstenHans\">ThorstenHans<\/a> and <a href=\"https:\/\/github.com\/zachcarroll\">zachcarroll<\/a> for your contributions. I hope you are satisfied with how ADAL JS came out, and I can\u2019t wait to see what you will achieve with it <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2015\/02\/wlEmoticon-smile2.png\" alt=\"Smile\" \/> Happy coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Less than 4 months ago I wrote at length about the first preview of ADAL JS, a new library meant to help you to take advantage of Azure AD to secure your SPA apps and consume Web API from JavaScript. Since then we\u2019ve been iterating on the library surface and architecture, ingesting your&#8230;<\/p>\n","protected":false},"author":1,"featured_media":3198,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"categories":[72,1],"tags":[123],"class_list":["post-3193","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-access-control","category-uncategorized","tag-adaljs"],"_links":{"self":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/3193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/comments?post=3193"}],"version-history":[{"count":5,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/3193\/revisions"}],"predecessor-version":[{"id":3736,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/3193\/revisions\/3736"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/3198"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=3193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=3193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=3193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}