【Azure 應用服務】NodeJS Express + MSAL 應用實現AAD登錄並獲取AccessToken — cca.acquireTokenByCode(tokenRequest)
- 2022 年 6 月 8 日
- 筆記
- 【Azure Developer】, 【Azure 應用服務】, 【Azure 環境】, App Service, Azure Developer, Azure 環境, cca.acquireTokenByCode(tokenRequest), MSAL AAD
問題描述
在上一篇博文 「【Azure 應用服務】NodeJS Express + MSAL 應用實現AAD集成登錄並部署在App Service Linux環境中的實現步驟」中,實現了登錄,並獲取登錄用戶在AAD中的個人信息,但是沒有一個顯示的方法輸出所獲取到的Access Token,則通過新建Express項目,加載MSAL的代碼實現此目的。
實現步驟
第一步:創建 NodeJS Express項目,並添加@azure/msal-node 項目包
前提條件:安裝 Node.js 和 VS Code
使用npm安全express項目生成器
npm install -g express-generator
在當前目錄在生成 express項目默認文件
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 參數 clientId, authority 和 clientSecret (與上一篇博文中第一步相同, 也需要添加 //localhost:3000/redirect 在 AAD註冊應用的Redirect URIs中)。
// Authentication parameters const config = { auth: { clientId: " Enter_the_Application_Id_Here", authority: "//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 = "//localhost:3000/redirect";
然後根據上一步的config參數初始化 msal confidential client applicaiton對象
// Initialize MSAL Node object using authentication parameters const cca = new msal.ConfidentialClientApplication(config);
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: "//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 = "//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 應用實現AAD集成登錄並部署在App Service Linux環境中的實現步驟://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: //docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal
Example: Acquiring tokens with ADAL Node vs. MSAL Node://docs.microsoft.com/en-us/azure/active-directory/develop/msal-node-migration#example-acquiring-tokens-with-adal-node-vs-msal-node