I'm trying to figure out how you can authenticate users using Azure AD. In order to experiment, I tried the example from Microsoft, found at https://github.com/Azure-Samples/active-directory-node-webapp-openidconnect.
I've set up an Active Directory in Azure, and added a new application called test with add id uri: http://testmagnhalv.
Now, when I run the server, following the instructions in the readme, I get redirected to login.microsoftonline.com and promted to log in. But when I provide username/pw, I get redirected back to the login page again.
I suspect the problem is that I don't set the variables in the config.json correctly, but I'm having a hard time finding documentation for what values need to be set.
Anyone got any experience with this example?
At first you must to add your app to active directory then use ADAL (Active Directory Authentication Library) for nodeJS
npm install adal-node
prepare your app for authentication referencing azure AD App registration values.
var AuthenticationContext = require('adal-node').AuthenticationContext;
var clientId = 'yourClientIdHere';
var clientSecret = 'yourAADIssuedClientSecretHere'
var redirectUri = 'yourRedirectUriHere';
var authorityHostUrl = 'https://login.windows.net';
var tenant = 'myTenant';
var authorityUrl = authorityHostUrl + '/' + tenant;
var redirectUri = 'http://localhost:3000/getAToken';
var resource = '00000002-0000-0000-c000-000000000000';
var templateAuthzUrl = 'https://login.windows.net/' +
tenant +
'/oauth2/authorize?response_type=code&client_id=' +
clientId +
'&redirect_uri=' +
redirectUri + '
&state=<state>&resource=' +
resource;
Now you need to get authorized with the token.
function createAuthorizationUrl(state) {
return templateAuthzUrl.replace('<state>', state);
}
// Clients get redirected here in order to create an OAuth authorize url and redirect them to AAD.
// There they will authenticate and give their consent to allow this app access to
// some resource they own.
app.get('/auth', function(req, 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);
});
});
And finally handle the auth redirection
// After consent is granted AAD redirects here. The ADAL library is invoked via the
// AuthenticationContext and retrieves an access token that can be used to access the
// user owned resource.
app.get('/getAToken', function(req, res) {
if (req.cookies.authstate !== req.query.state) {
res.send('error: state does not match');
}
var authenticationContext = new AuthenticationContext(authorityUrl);
authenticationContext.acquireTokenWithAuthorizationCode(
req.query.code,
redirectUri,
resource,
clientId,
clientSecret,
function(err, response) {
var errorMessage = '';
if (err) {
errorMessage = 'error: ' + err.message + '\n';
}
errorMessage += 'response: ' + JSON.stringify(response);
res.send(errorMessage);
}
);
});
You can find the full example, and more here in ADAL for nodeJS repository:
Windows Azure Active Directory Authentication Library (ADAL) for Node.js
This is a simple but full demo taken from GitHub ADAL repository
'use strict';
var express = require('express');
var logger = require('connect-logger');
var cookieParser = require('cookie-parser');
var session = require('cookie-session');
var fs = require('fs');
var crypto = require('crypto');
var AuthenticationContext = require('adal-node').AuthenticationContext;
var app = express();
app.use(logger());
app.use(cookieParser('a deep secret'));
app.use(session({secret: '1234567890QWERTY'}));
app.get('/', function(req, res) {
res.redirect('login');
});
/*
* You can override the default account information by providing a JSON file
* with the same parameters as the sampleParameters variable below. Either
* through a command line argument, 'node sample.js parameters.json', or
* specifying in an environment variable.
* {
* "tenant" : "rrandallaad1.onmicrosoft.com",
* "authorityHostUrl" : "https://login.windows.net",
* "clientId" : "624ac9bd-4c1c-4686-aec8-e56a8991cfb3",
* "clientSecret" : "verySecret="
* }
*/
var parametersFile = process.argv[2] || process.env['ADAL_SAMPLE_PARAMETERS_FILE'];
var sampleParameters;
if (parametersFile) {
var jsonFile = fs.readFileSync(parametersFile);
if (jsonFile) {
sampleParameters = JSON.parse(jsonFile);
} else {
console.log('File not found, falling back to defaults: ' + parametersFile);
}
}
if (!parametersFile) {
sampleParameters = {
tenant : 'rrandallaad1.onmicrosoft.com',
authorityHostUrl : 'https://login.windows.net',
clientId : '624ac9bd-4c1c-4686-aec8-b56a8991cfb3',
username : '[email protected]',
password : ''
};
}
var authorityUrl = sampleParameters.authorityHostUrl + '/' + sampleParameters.tenant;
var redirectUri = 'http://localhost:3000/getAToken';
var resource = '00000002-0000-0000-c000-000000000000';
var templateAuthzUrl = 'https://login.windows.net/' + sampleParameters.tenant + '/oauth2/authorize?response_type=code&client_id=<client_id>&redirect_uri=<redirect_uri>&state=<state>&resource=<resource>';
app.get('/', function(req, res) {
res.redirect('/login');
});
app.get('/login', function(req, res) {
console.log(req.cookies);
res.cookie('acookie', 'this is a cookie');
res.send('\
<head>\
<title>FooBar</title>\
</head>\
<body>\
<a href="./auth">Login</a>\
</body>\
');
});
function createAuthorizationUrl(state) {
var authorizationUrl = templateAuthzUrl.replace('<client_id>', sampleParameters.clientId);
authorizationUrl = authorizationUrl.replace('<redirect_uri>',redirectUri);
authorizationUrl = authorizationUrl.replace('<state>', state);
authorizationUrl = authorizationUrl.replace('<resource>', resource);
return authorizationUrl;
}
// Clients get redirected here in order to create an OAuth authorize url and redirect them to AAD.
// There they will authenticate and give their consent to allow this app access to
// some resource they own.
app.get('/auth', function(req, 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);
});
});
// After consent is granted AAD redirects here. The ADAL library is invoked via the
// AuthenticationContext and retrieves an access token that can be used to access the
// user owned resource.
app.get('/getAToken', function(req, res) {
if (req.cookies.authstate !== req.query.state) {
res.send('error: state does not match');
}
var authenticationContext = new AuthenticationContext(authorityUrl);
authenticationContext.acquireTokenWithAuthorizationCode(req.query.code, redirectUri, resource, sampleParameters.clientId, sampleParameters.clientSecret, function(err, response) {
var message = '';
if (err) {
message = 'error: ' + err.message + '\n';
}
message += 'response: ' + JSON.stringify(response);
if (err) {
res.send(message);
return;
}
// Later, if the access token is expired it can be refreshed.
authenticationContext.acquireTokenWithRefreshToken(response.refreshToken, sampleParameters.clientId, sampleParameters.clientSecret, resource, function(refreshErr, refreshResponse) {
if (refreshErr) {
message += 'refreshError: ' + refreshErr.message + '\n';
}
message += 'refreshResponse: ' + JSON.stringify(refreshResponse);
res.send(message);
});
});
});
app.listen(3000);
console.log('listening on 3000');
https://github.com/AzureAD/azure-activedirectory-library-for-nodejs/blob/master/sample/website-sample.js
As I known, I suggest you can follow the two documents below as references to get start.
For developing easier, you can try to use the node package passport-azure-ad
(https://github.com/AzureAD/passport-azure-ad) that is the one strategy of passport
(http://passportjs.org/) for NodeJS to implement your needs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With