Questions? Feedback? powered by Olark live chat software
Hoppa över navigering

How to authorize Node.js API with Azure AD

Senast uppdaterad: 2016-11-01
Deltagare:
Redigera på GitHub

Introduction

This is a web app sample with Node.js, and it demonstrates how to authorize Node.js API with Azure AD,
It uses the adal-node library to authorize with Azure AD.
In this sample, you can test the authorized Node.js API with Azure AD.

Sample prerequisites

To open and run this asmple, ensure that the following requisites have been met: - Node.js 6.6.0 or above. - NPM is installed (In default case, it has to be installed before you installed Node.js). - You have subcribed the Azure and you have the permission to manage Azure Active Directory on your subscription.

Building the sample

Restore the library
- Open the Command Prompt window and navigate to sample location folder. In this case, the sample location is D:\Sample\JSAzureADAuthWithNodeJS.
- Install the libraries
- npm install express - npm install cookie-parser - npm install cookie-session - npm install crypto - npm install adal-node

Configuration App in Azure - Go to https://code.msdn.microsoft.com/How-to-authorize-Nodejs-fdc580ed/https://portal.azure.com and login. - In the left panel, find Azure Active Directory and click, or click more services to find the Azure Active Directory in prop panel.

  • Click the App registrations in manage panel from Azure Active Directory.

  • Click the add button.

  • Fill in the Name and Sign-on URL, and choose the Application Type as Web app / API. Finally, click Create button.

  • Then you can notice the app has been created and appeared in the app list, click to open it.

  • After that, you can see the below UI, click Settings.

  • Click Reply URLs, then change address as http://localhost:3000/getAToken. Finally, click the Save button.

  • Click Keys, then type a string in field DESCRIPTION, Choose EXPIRES as Never expires, type a string to the VALUE field, then click Save button.
    After you have successfully created the key, copy its valuedown. Since it shows only once, you won’t be able to retrieve again after you leave this blade.

Configuration parameters
Open the file server.js and configuration flowing field. - Tenant
You can find it in dashboard. - clientID Azure Active Directory -> Appregistrations -> application of you created -> copy the Application ID down.

  • secret application of you created -> Settings -> Keys -> you copied value.

Running the sample

  • Open the Command Prompt window and navigate to sample location folder, in this case, the sample location is D:\Sample\JSAzureADAuthWithNodeJS.

  • Type command: node server.js so that the web server will be running.

  • Open the browser, and go to http://localhost:3000, click the Login link.

  • Type your Microsoft account info. Note: this account must be the member in your Azure AD.

  • After the authorization has been finished, you can see the below page which contains all the authorization information.

Using the code

Auth.js ```javascript 'use strict';

var crypto = require('crypto'); var AuthenticationContext = require('adal-node').AuthenticationContext;

module.exports = { Create:function(params){ var authObj = { tenant:params.tenant, clientId:params.clientId, secret:params.secret, redirectUri:params.redirectUri };

    authObj.authorityHostUrl = "https://login.windows.net";
    authObj.authorityUrl = authObj.authorityHostUrl + "/" + authObj.tenant;
    authObj.resource = "00000002-0000-0000-c000-000000000000";
    authObj.templateAuthzUrl = 'https://login.windows.net/' + authObj.tenant + '/oauth2/authorize?response_type=code&client_id=<client_id>&redirect_uri=<redirect_uri>&state=<state>&resource=<resource>';

    authObj.loginIfNotAuth = function(req,res,action){
        if(isAuthored(req))
        {
            if(isExpire(req))
            {
                authObj.refreshToken(req,res,action);
            }
            else{
                action();
            }
        }
        else
        {
            authWithAzureAD(res);
        }
    };

    authObj.receiveToken = function(req,res,action){
        if (req.cookies.authstate !== req.query.state) {
            res.send('error: state does not match');
            return;
        }

        var authenticationContext = new AuthenticationContext(authObj.authorityUrl);
        authenticationContext.acquireTokenWithAuthorizationCode(req.query.code, authObj.redirectUri, authObj.resource, authObj.clientId, authObj.secret, function(err, response) {
            var message = '';
            if (err) {
                message = 'error: ' + err.message;
                res.send(message);
                return;
            }
            response.requestOn = Date.now();
            //set token to session
            req.session.authInfo = response;
            //do the action
            if(action){
                action();
            }
        });
    };

    authObj.refreshToken = function(req,res,action) {
        var authenticationContext = new AuthenticationContext(authObj.authorityUrl);
        authenticationContext.acquireTokenWithRefreshToken(req.session.authInfo.refreshToken, authObj.clientId, authObj.secret, authObj.resource, function(refreshErr, refreshResponse) {
            if (refreshErr) {
                var message = 'refreshError: ' + refreshErr.message;
                res.send(message); 
                return;
            }
            refreshResponse.requestOn = Date.now();
            //set token to session
            req.session.authInfo = refreshResponse;
            //do the action
            if(action){
                action();
            }
        }); 
    };

    function authWithAzureAD(res){
        crypto.randomBytes(48, function(ex, buf) {
            var token = buf.toString('base64').replace(/\//g,'_').replace(/\+/g,'-');

            res.cookie('authstate', token);
            var authorizationUrl = createAuthorizationUrl(token);

            res.redirect(authorizationUrl);
        });
    }

    function isAuthored(req){
        return req.session.authInfo;
    }

    function isExpire(req){
        var now = Date.now();
        var requestOn = req.session.authInfo.requestOn;
        var expiresIn = req.session.authInfo.expiresIn * 1000;
        return requestOn + expiresIn >= Date.now();
    }

    function createAuthorizationUrl(state) {
        var authorizationUrl = authObj.templateAuthzUrl.replace('<client_id>', authObj.clientId)
            .replace('<redirect_uri>',authObj.redirectUri)
            .replace('<state>', state)
            .replace('<resource>', authObj.resource);
        return authorizationUrl;
    }

    return authObj;
}

}; ```

Server.js ``` javascript 'use strict';

var express = require('express'); var cookieParser = require('cookie-parser'); var cookieSession = require('cookie-session');

var authObj = require("./Auth.js").Create({ tenant:"", clientId:"", secret:"", redirectUri:"http://localhost:3000/getAToken" });

var app = express(); app.use(cookieParser('a deep secret')); app.use(cookieSession({name: 'session',keys: [""]}));

app.get('/', function(req, res) { res.end('\ \ test\ \ \ Login\ \ '); });

app.get('/auth', function(req, res) { authObj.loginIfNotAuth(req,res,function(){ res.send("authed"); }); });

app.get('/getAToken', function(req, res) { authObj.receiveToken(req,res,function(){ res.redirect('/AuthInfo'); }); });

app.get('/AuthInfo', function(req, res) { var sessionValue = req.session.authInfo; var authString = JSON.stringify(sessionValue); var userID = sessionValue.userId; var familyName = sessionValue.familyName; var givenName = sessionValue.givenName;

res.end(`\
    <h1>UserID: ${userID}</h1>
    <h2>familyName: ${familyName}</h2>
    <h2>givenName: ${givenName}</h2>
    <h2>full data:</h2>
    <p>${authString}</p>
`);

});

app.listen(3000); console.log("listen 3000"); ```

More information