Using Active Directory Federation Services (ADFS) to Authenticate / Authorize Node.js Apps in Windows Azure

Using Active Directory Federation Services (ADFS) to Authenticate / Authorize Node.js Apps in Windows Azure

Azure integration with Active directoryIt’s gotten easy to publish web applications to the cloud, but the last thing you want to do is establish unique authentication schemes for each one. At some point, your users will be stuck with a mountain of passwords, or, end up reusing passwords everywhere. Not good. Instead, what about extending your existing corporate identity directory to the cloud for all applications to use? Fortunately, Microsoft Active Directory can be extended to support authentication/authorization for web applications deployed in ANY cloud platform. In this post, I’ll show you how to configure Active Directory Federation Services (ADFS) to authenticate the users of a Node.js application hosted in Windows Azure Web Sites and deployed via Dropbox.

[Note: I was going to also show how to do this with an ASP.NET application since the new “Identity and Access” tools in Visual Studio 2021 make it really easy to use ADFS to authenticate users. However because of the passive authentication scheme Windows Identity Foundation uses in this scenario, the ASP.NET application has to be secured by SSL/TLS. Windows Azure Web Sites doesn’t support HTTPS (yet), and getting HTTPS working in Windows Azure Cloud Services isn’t trivial. So, we’ll save that walk-through for another day.

Configuring Active Directory Federation Services for our application

Azure integration with Active directory_2

First off, I created a server that had DNS services and Active Directory installed. This server sits in the Tier 3 cloud and I used our orchestration engine to quickly build up a box with all the required services. Check out this KB article I wrote for Tier 3 on setting up an Active Directory and ADFS server from scratch.

ADFS is a service that supports identity federation and supports industry standards like SAML for authenticating users. It returns claims about the authenticated user. In ADFS, you’ve got endpoints that define which inbound authentication schemes are supported (like WS-Trust or SAML),  certificates for signing tokens and securing transmissions, and relying parties which represent the endpoints that ADFS has a trust relationship with.

Azure integration with Active directory_2.5In our case, I needed to enabled an active endpoint for my Node.js application to authenticate against, and one new relying party. First, I created a new relying party that referenced the yet-to-be-created URL of my Azure-hosted web site. In the animation below, see the simple steps I followed to create it. Note that because I’m doing active (vs. passive) authentication, there’s no endpoint to redirect to, and very few overall required settings.

Active directory integration with Azure_3


  • Visualize your Azure resources and usage patterns
  • Associate business activities with cloud usage
  • Leverage Azure crowd sourced knowledge and best practices

Sign Up for Newvem Analytics for Azure


Active directory integration with Azure_3.5

At this point, ADFS was fully configured and able to authenticate my remote application. The final thing to do was enable the appropriate authentication endpoint. By default, the password-based WS-Trust endpoint is disabled, so I flipped it on so that I could pass username+password credentials to ADFS and authenticate a user.

Azure integration with Active directory_5

Connecting a Node.js application to AD FS

Next, I used the JetBrains WebStorm IDE to build a Node.js application based on the Express framework. This simple application takes in a set of user credentials, and attempts to authenticate those credentials against ADFS. If successful, the application displays all the Active Directory Groups that the user belongs to. This information could be used to provide a unique application experience based on the role of the user. The initial page of the web application takes in the user’s credentials.

div.content
h1= title
form(action='/profile', method='POST')
table
tr
td
label(for='user') User
td
input(id='user', type='text', name='user')
tr
td
label(for='password') Password
td
input(id='password', type='password', name='password')
tr
td(colspan=2)
input(type='submit', value='Log In')

This page posts to a Node.js route (controller) that is responsible passing those credentials to ADFS. How do we talk to ADFS through the WS-Trust format? Fortunately, Leandro Boffi wrote up a simple Node.js module that does just that. I grabbed the wstrust-client module and added it to my Node.js project. The WS-Trust authentication response comes back as XML, so I also added a Node.js module to convert XML to JSON for easier parsing. My route code looked like this:

//for XML parsing
var xml2js = require('xml2js');
var https = require('https');
//to process WS-Trust requests
var trustClient = require('wstrust-client');</p>
<p>exports.details = function(req, res){</p>
<p>var userName = req.body.user;
var userPassword = req.body.password;</p>
<p>//call endpoint, and pass in values
trustClient.requestSecurityToken({
scope: 'http://seroternodeadfs.azurewebsites.net',
username: userName,
password: userPassword,
endpoint: 'https://[AD FS server IP address]/adfs/services/trust/13/UsernameMixed'
}, function (rstr) {</p>
<p>// Access the token
var rawToken = rstr.token;
console.log('raw: ' + rawToken);</p>
<p>//convert to json
var parser = new xml2js.Parser;
parser.parseString(rawToken, function(err, result){
//grab "user" object
var user = result.Assertion.AttributeStatement[0].Attribute[0].AttributeValue[0];
//get all "roles"
var roles = result.Assertion.AttributeStatement[0].Attribute[1].AttributeValue;
console.log(user);
console.log(roles);</p>
<p>//render the page and pass in the user and roles values
res.render('profile', {title: 'User Profile', username: user, userroles: roles});
});
}, function (error) {</p>
<p>// Error Callback
console.log(error)
});
};

See that I’m providing a “scope” (which maps to the relying party identifier), an endpoint (which is the public location of my ADFS server), and the user-provided credentials to the WS-Trust module. I then parse the results to grab the friendly name and roles of the authenticated user. Finally, the “profile” page takes the values that it’s given and renders the information.

div.content
h1 #{title} for #{username}
br
div
div.roleheading User Roles
ul
each userrole in userroles
li= userrole

My application was complete and ready for deployment to Windows Azure - Check out how to publish a Node.js application to Windows Azure Cloud.

Testing the application

The whole point of this application is to authenticate a user and return their Active Directory role collection. I created a “Richard Seroter” user in my Active Directory and put that user in a few different Active Directory Groups.

Azure integration with Active directory_13

I then browsed to my Windows Azure Website URL and was presented with my Node.js application interface.

Azure integration with Active directory_14

Azure integration with Active directory_14

I plugged in my credentials and was immediately presented with the list of corresponding Active Directory user group membership information.

Azure integration with Active directory_15

 

Summary

That was fun. ADFS is a fantastic way to extend your on-premises directory to applications hosted outside of your corporate network. In this case, we saw how to create  Node.js application that authenticated users against ADFS. While I deployed this sample application to Windows Azure Web Sites, I could have deployed this to ANY cloud that supports Node.js. Imagine having applications written in virtually any language, and hosted in any cloud, all using a single authentication endpoint. Powerful stuff!

About the Author

richard-seroter-v2

Richard Seroter is a Product Manager for cloud computing provider Tier 3, a Microsoft MVP, blogger, author, trainer and frequent public speaker. He has spent the majority of his career working with organizations as they planned and implemented their enterprise software solutions. Richard worked first for two global IT consulting firms where he gained exposed to a diverse range of industries, technologies, and business challenges. Then, Richard joined Microsoft as a SOA/BPM technology specialist where his sole objective was to educate and collaborate with customers as they considered, designed, and built application integration solutions. He then accepted a job at biotechnology leader Amgen where he designed a wide range of global systems before becoming the lead architect of the R&D division. Richard now works at Tier 3 as a Product Manager where he contributes to product strategy and development while actively collaborating with the cloud computing community. Richard is the author or contributor to three recent books: “Applied Architecture Patterns on the Microsoft Platform” (Packt Publishing, 2020) , “SOA Patterns with BizTalk Server 2009? (Packt Publishing, 2009) , and “Microsoft BizTalk 2020: Line of Business Systems Integration” (Packt Publishing, 2011).

Contact him

Originally posted here - http://seroter.wordpress.com/2022/04/22/using-active-directory-federation-services-to-authenticate-authorize-node-js-apps-in-windows-azure/

Keywords: Microsoft Azure, Windows Azure, Azure Cloud, Azure Public Cloud, Virtual Machines, Node.js, Dropbox, SDK, Active Directory Federation Services, ASDF, Security, SAML, IAM, Security, Users Management, Cloud, Node.js, Enterprise Cloud Platform, Windows Azure, Identity and Access Management, Javascript, Webserver

You must be to post a comment.

* As a bonus, you'll receive our weekly newsletter!

Hitchhiker's Guide to The Cloud

Newvem's eBook for Cloud Operations