• 【Azure 应用服务】NodeJS Express + MSAL 应用实现AAD登录并获取AccessToken cca.acquireTokenByCode(tokenRequest)


    问题描述

    在上一篇博文 “【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 (与上一篇博文中第一步相同, 也需要添加 http://localhost:3000/redirect 在 AAD注册应用的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";

    然后根据上一步的config参数初始化 msal confidential client applicaiton对象

    // Initialize MSAL Node object using authentication parameters
    const cca = new msal.ConfidentialClientApplication(config);
     
    最后,实现 /auth 和 /redirect 接口代码 (/auth 是登录AAD的入口,登录成功后由AAD回调/redirect接口,输出Access Token内容
    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 应用实现AAD集成登录并部署在App Service Linux环境中的实现步骤: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

  • 相关阅读:
    操作符的详解
    一切皆对象
    对象导论
    mysql
    bootstrap学习
    素数筛选法
    python的urllib库
    是做应用还是搞算法?
    金山词霸笔试题目笔记
    双十一,更是技术的战争~~
  • 原文地址:https://www.cnblogs.com/lulight/p/16357246.html
Copyright © 2020-2023  润新知