1

我们有一个具有 MSAL 登录的前端反应应用程序,该应用程序使用 aws api 网关 api 端点进行后端操作。在登录过程之后,我想将承载令牌发送到 api 并对其进行身份验证。根据我在线阅读的内容,您可以使用 node.js 和 passport.authenticate() 来执行此操作。问题是试图在 aws api 网关中进行这项工作。所以我想出了一个通过 Authorizer lambda 进行身份验证的方案。1) 使用 aws-serverless-express 在 lambda 中将 express 作为 api 代理运行 2) 使用 passport-azure-ad 模块设置承载策略。3) 运行 passport.authenticate() 来验证令牌。4) 在 lambda 的有效令牌返回允许策略 5) api 请求将继续

我刚刚将以下文件和所需的节点模块放入 node.js lambda。所以这本质上是客户端和 api 之间的中间件。如果令牌有效,将允许请求通过。

在我的测试中,当它应用承载策略时出现此错误:

{ "name": "AzureAD: Bearer Strategy", "hostname": "169.254.43.173", "pid": 8, "level": 30, "msg": "authentication failed due to: token is not found", “时间”:“2020-08-24T23:48:35.497Z”,“v”:0 }

如果有一种更简单的方法来验证承载令牌,那就太好了。

Lambda index.js 文件:

const awsServerlessExpress = require('aws-serverless-express')
const app = require('./app')
const server = awsServerlessExpress.createServer(app)

exports.handler = (event, context) => awsServerlessExpress.proxy(server, event, context)

配置.js

'use strict';

const config = {
    identityMetadata: "https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration",
    clientID: "xxxxxxxxxxxxxxxxxxxx",
    validateIssuer: true,
    loggingLevel: 'info',
    passReqToCallback: false,
    ignoreExpiration: true
};

module.exports = config

app.js 文件

'use strict'
const express = require('express')
const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware')
const passport = require("passport");
const config = require('./config');
const BearerStrategy = require('passport-azure-ad').BearerStrategy;
const bearerStrategy = new BearerStrategy(config, (token, done) => {
    // Send user info using the second argument
    done(null, {}, token);
}
);
const app = express();
app.use(passport.initialize());
const router = express.Router()
passport.use(bearerStrategy);

router.use(awsServerlessExpressMiddleware.eventContext())

var generatePolicy = function(effect, resource) {
    var authResponse = {};
    authResponse.principalId = 'user';
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; // default version
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; // default action
        statementOne.Effect = effect;
        statementOne.Resource = "*";
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    return authResponse;
}
        
var generateAllow = function(resource) {
    return generatePolicy('Allow', resource);
}

router.get('/', passport.authenticate('oauth-bearer', {session: false}),
    (req, res) => {
        res.send(generateAllow(req.apiGateway.event.methodArn))        
    }
);

// The aws-serverless-express library creates a server and listens on a Unix
// Domain Socket for you, so you can remove the usual call to app.listen.
// app.listen(3000)
app.use('/', router)

// Export your express server so you can import it in the lambda function.
module.exports = app
4

0 回答 0