1

我正在 node.js 中编写 AWS lambda Authorizer。我们需要调用 Azure AD API 来获取公钥/安全策略来验证传入的访问令牌。

但是,为了优化性能,我决定将 node.js 中的公钥/安全策略存储为常量(这将一直有效,直到 Lambda 正在运行或密钥的 TTL 过期)。

问题:从安全角度来看,它安全吗?我想避免在 DynamoDB 中“缓存”它,因为对 DynamoDB 的调用也会产生额外的毫秒数。我们的应用程序是一个非常高流量的应用程序,我们希望节省任何可能的毫秒以获得最佳性能。此外,任何最佳实践也受到高度赞赏

4

1 回答 1

0

通常,您不应该在代码中硬编码类似的内容。尽管这不是安全问题,但它使维护变得更加困难。

例如:当密钥“轮换”或策略更改并且您在 Lambda 中对其进行硬编码时,您需要更新代码并进行另一次部署。这通常会导致问题,因为开发人员忘记了这一点等导致问题,因为您的授权人不再工作。如果 Lambda 从外部服务(如 S3、SSM 或直接 Azure AD)加载信息,则不需要其他部署。从理论上讲,它应该根据您使用的服务以及管理密钥的方式等自行解决。

我认为最好的方法是在 Lambda的初始化阶段从外部服务加载密钥。这意味着当它第一次“启动”时,然后在 Lambdas 生命周期(几分钟到几小时)内缓存该值。

例如,您可以直接从 Azure、S3 或 SSM Parameter Store 加载公钥和策略。

以下代码使用未与 Lambda 运行时捆绑的 AWS 开发工具包 NodeJS v3。您也可以使用 SDK 的 v2。

const { SSMClient, GetParameterCommand } = require("@aws-sdk/client-ssm");

// This only happens once, when the Lambda is started for the first time:
const init = async () => {
    const config = {}

    try {
        // use whatever 'paramName' you defined, when you created the SSM parameter
        const paramName = "/azure/publickey"
        const command = new GetParameterCommand({Name: paramName});
        const ssm = new SSMClient();
        const data = await ssm.send(command);
        config["publickey"] = data.Parameter.Value;
    } catch (error) {
        return Promise.reject(new Error("unable to read SSM parameter '"+ paramName + "'."));
    }

    return new Promise((resolve, reject) => {
        resolve(config);
        reject(new Error("unable to create configuration. Unknown error."));
    });
};

const initPromise = init();

exports.handler = async (event) => {
    const config = await initPromise;

    console.log("My public key '%s'", config.key);

    return "Hello World";
};

这段代码最重要的一点是init“函数”,它只运行一次,创建一个“配置”,其中应该包含您的 AWS 开发工具包客户端和代码中需要的所有配置。这样,您不必为 Lambda 正在处理的每个请求等获取策略。

于 2021-06-23T07:30:34.817 回答