問題描述
在上一篇博文 “【Azure 應(yīng)用服務(wù)】NodeJS Express + MSAL 應(yīng)用實現(xiàn)AAD集成登錄并部署在App Service Linux環(huán)境中的實現(xiàn)步驟”中溺拱,實現(xiàn)了登錄凰兑,并獲取登錄用戶在AAD中的個人信息似舵,但是沒有一個顯示的方法輸出所獲取到的Access Token,則通過新建Express項目衰腌,加載MSAL的代碼實現(xiàn)此目的。
實現(xiàn)步驟
第一步:創(chuàng)建 NodeJS Express項目觅赊,并添加@azure/msal-node 項目包
前提條件:安裝 Node.js 和 VS Code
使用npm安全express項目生成器
npm install -g express-generator
在當(dāng)前目錄在生成 express項目默認(rèn)文件
express --view=hbs
開始生成項目文件
npm install
安裝MSAL package
npm install --save @azure/msal-node
項目生成后的完整路徑
myExpressWebApp/ ├── bin/
| └── wwww
├── public/
| ├── images/
| ├── javascript/
| └── stylesheets/
| └── style.css
├── routes/
| ├── index.js | └── users.js
├── views/
| ├── error.hbs | ├── index.hbs | └── layout.hbs
├── app.js
└── package.json
第二步:在 app.js 中添加 MSAL object画畅,添加 '/auth' 接口登錄AAD并獲取Access Token
引入 msal 對象
const msal = require('@azure/msal-node');
配置AAD Authentication 參數(shù) clientId, authority 和 clientSecret (與上一篇博文中第一步相同, 也需要添加 http://localhost:3000/redirect 在 AAD注冊應(yīng)用的Redirect URIs中)驳概。
// Authentication parameters
const config = {
auth: {
clientId: " Enter_the_Application_Id_Here",
authority: "https://login.partner.microsoftonline.cn/<#Enter_the_Tenant_Info_Here>",
clientSecret: "xxxxxx.xxxxxxxxxxxxxxxxx" #Enter_the_Client_Secret_Here
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
}
}
};
const REDIRECT_URI = "http://localhost:3000/redirect";
然后根據(jù)上一步的config參數(shù)初始化 msal confidential client applicaiton對象
// Initialize MSAL Node object using authentication parameters
const cca = new msal.ConfidentialClientApplication(config);
最后,實現(xiàn) /auth 和 /redirect 接口代碼 (/auth 是登錄AAD的入口,登錄成功后由AAD回調(diào)/redirect接口棕所,輸出Access Token內(nèi)容
app.get('/auth', (req, res) => { // Construct a request object for auth code
const authCodeUrlParameters = {
scopes: ["user.read"],
redirectUri: REDIRECT_URI,
}; // Request auth code, then redirect
cca.getAuthCodeUrl(authCodeUrlParameters)
.then((response) => {
res.redirect(response);
}).catch((error) => res.send(error));
});
app.get('/redirect', (req, res) => { // Use the auth code in redirect request to construct
// a token request object
const tokenRequest = {
code: req.query.code,
scopes: ["user.read"],
redirectUri: REDIRECT_URI,
}; // Exchange the auth code for tokens
cca.acquireTokenByCode(tokenRequest)
.then((response) => {
res.send(response);
}).catch((error) => res.status(500).send(error));
});
完整 app.js 代碼為:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
const msal = require('@azure/msal-node');
// Authentication parameters
const config = {
auth: {
clientId: " Enter_the_Application_Id_Here",
authority: "https://login.partner.microsoftonline.cn/<#Enter_the_Tenant_Info_Here>",
clientSecret: "xxxxxx.xxxxxxxxxxxxxxxxx" #Enter_the_Client_Secret_Here
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
}
}
};
const REDIRECT_URI = "http://localhost:3000/redirect";
// Initialize MSAL Node object using authentication parameters
const cca = new msal.ConfidentialClientApplication(config);
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.get('/auth', (req, res) => {
// Construct a request object for auth code
const authCodeUrlParameters = {
scopes: ["user.read"],
redirectUri: REDIRECT_URI,
};
// Request auth code, then redirect
cca.getAuthCodeUrl(authCodeUrlParameters)
.then((response) => {
res.redirect(response);
}).catch((error) => res.send(error));
});
app.get('/redirect', (req, res) => {
// Use the auth code in redirect request to construct
// a token request object
const tokenRequest = {
code: req.query.code,
scopes: ["user.read"],
redirectUri: REDIRECT_URI,
};
// Exchange the auth code for tokens
cca.acquireTokenByCode(tokenRequest)
.then((response) => {
res.send(response);
}).catch((error) => res.status(500).send(error));
});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
運行效果動畫展示:
參考資料
NodeJS Express + MSAL 應(yīng)用實現(xiàn)AAD集成登錄并部署在App Service Linux環(huán)境中的實現(xiàn)步驟:https://www.cnblogs.com/lulight/p/16353145.html
Tutorial: Sign in users and acquire a token for Microsoft Graph in a Node.js & Express web app: https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal
Example: Acquiring tokens with ADAL Node vs. MSAL Node:https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-node-migration#example-acquiring-tokens-with-adal-node-vs-msal-node
當(dāng)在復(fù)雜的環(huán)境中面臨問題仗嗦,格物之道需:濁而靜之徐清沽一,安以動之徐生秘案。 云中,恰是如此!
分類: 【Azure 應(yīng)用服務(wù)】, 【Azure 環(huán)境】, 【Azure Developer】
標(biāo)簽: App Service, Azure Developer, Azure 環(huán)境, MSAL AAD, cca.acquireTokenByCode(tokenRequest)