简体   繁体   English

API 网关授权方 - IAM 策略未缓存

[英]API Gateway Authorizer - IAM policy not caching

I am trying to cache the IAM policy returned by the authorizer lambda when it validates the JWT token for the first time.我正在尝试缓存授权方 lambda 首次验证 JWT 令牌时返回的 IAM 策略。 I have enabled and set the authorizerResultTtlInSeconds to 3500 seconds in API Gateway Authorizer.我已在 API 网关授权器中启用并将authorizerResultTtlInSeconds设置为3500秒。 However, I still see a request going to the Authorizer lambda function within the caching time frame.但是,我仍然看到在缓存时间范围内向授权方 lambda function 发送请求。

My node.js script is as below:我的 node.js 脚本如下:

const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');

const keyClient = jwksClient({
    jwksUri: process.env.JWKS_URI
})

const allow = {
    "principalId": "user",
    "policyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": "execute-api:Invoke",
                "Effect": "Allow",
                "Resource": process.env.RESOURCE // RESOURCE = *
            }
        ]
    }
}

const unauthorized = {
    "error": "Unauthorized",
}

//excluded verificationJWTOptions object and getSigningKey function for simplicity
function validateJWTToken(token, callback) {
    jwt.verify(token, getSigningKey, verificationJWTOptions, (error) => {
        if (error) {
            callback(unauthorized)
        } else {
            callback(null, allow)
        }
    })
}

exports.handler = (event, context, callback) => {
    const token = extractTokenFromHeader(event);
    validateJWTToken(token, callback);
}

Not sure what I am missing out.不知道我错过了什么。 Any help would be much appreciated!任何帮助将非常感激!

I figured out that I wasn't testing the API Gateway Authorizer caching logic correctly.我发现我没有正确测试 API Gateway Authorizer 缓存逻辑。 I have been testing various scenarios and found two cases here:我一直在测试各种场景,在这里发现了两种情况:

  • When token is valid: When an endpoint is invoked, the request goes to the Lambda Authorizer which validates/invalidates the token.当令牌有效时:当调用endpoint ,请求会转到验证/使令牌无效的 Lambda 授权方。 An IAM policy is returned by the function to the API Gateway Authorizer and gets cached (in this case - for 58 minutes, 20 seconds ). IAM 策略由函数返回给 API Gateway Authorizer 并被缓存(在这种情况下 - 58 minutes, 20 seconds )。

    The header name specified in Token Source becomes the cache key and the authorization policy generated by the authorizer becomes the cache value. Token Source指定的头部名称成为缓存键,授权方生成的授权策略成为缓存值。 The API gateway will check the header specified in Token Source . API 网关将检查Token Source指定的标头。 If value of the header matches the key, API Gateway will not invoke the Lambda Authorizer and will instead check whether the policy is valid according to the configured TTL .如果 header 的值与 key 匹配,API Gateway 将不会调用 Lambda Authorizer 而是根据配置的TTL检查策略是否有效。

    If a new token gets generated within the caching time frame, then a call is made again to the Lambda Authorizer and this token gets cached.如果在缓存时间范围内生成了新令牌,则会再次调用 Lambda 授权程序并缓存此令牌。 Thus, if an endpoint is invoked using these two tokens, then no call is made to the Lambda Authorizer as IAM policies for these tokens are cached already for the given cache time frame and the response is got back.因此,如果使用这两个令牌调用终端节点,则不会调用 Lambda 授权程序,因为这些令牌的 IAM 策略已经在给定的缓存时间范围内缓存,并且响应会被返回。

  • When token is invalid: For instance, if the token is valid for 30 minutes from 11:00:00AM to 11:30:00AM , and the cache TTL is set to 58 minutes .当令牌无效时:例如,如果令牌在11:00:00AM11:30:00AM 30 minutes有效,并且缓存TTL设置为58 minutes The client makes 2 API requests using that token, one at 11:29:59AM and the other at 11:31:3APM - then both requests will be accepted although the second one used an expired token.客户端使用该令牌发出 2 个 API 请求,一个在11:29:59AM和另一个在11:31:3APM - 然后这两个请求都将被接受,尽管第二个请求使用了过期的令牌。 This basically means that the JWT token gets extended by the cache TTL .这基本上意味着JWT token被缓存TTL扩展。

I hit the same issue using AWS CDK.我使用 AWS CDK 遇到了同样的问题。 I believe this is a bug in CDK, CloudFormation or API Gateway itself.我相信这是 CDK、CloudFormation 或 API 网关本身的错误。

The workaround was to manually re-deploy the API Gateway stage.解决方法是手动重新部署 API 网关阶段。 Otherwise the caching option had no effect.否则缓存选项无效。

The deploy action can be found from the "Actions" menu in "Resources" section:可以从“资源”部分的“操作”菜单中找到部署操作:

重新部署操作

I believe this is a bug because AWS CDK should do this automatically by default because deploy: true is the default in RestApi construct:我认为这是一个错误,因为 AWS CDK 应该默认自动执行此操作,因为deploy: trueRestApi构造中的默认值:

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.RestApi.html#deploy https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.RestApi.html#deploy

Indicates if a Deployment should be automatically created for this API, and recreated when the API model (resources, methods) changes.指示是否应为此 API 自动创建 Deployment,并在 API model(资源、方法)更改时重新创建。

In CDK code I was able the force redeployment by renaming the RequestAuthorizer id:在 CDK 代码中,我能够通过重命名RequestAuthorizer id 来强制重新部署:

api.root
    .addResource("things")
    .addMethod("POST", new LambdaIntegration(nextHandler, {}), {
        apiKeyRequired: true,
        authorizer: new RequestAuthorizer(
            this,
            "Authorizer3", // 👈 Update this if you change resultsCacheTtl
            {
                // WARNING: resultsCacheTtl change requires manual
                // deployment from the AWS console. Or update the
                // RequestAuthorizer id
                resultsCacheTtl: Duration.minutes(5),
                handler: authorizer,
                identitySources: [IdentitySource.queryString("jwt")],
            },
        ),
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM