You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lambda@Edge无法获取Authorization请求头的问题求助

问题:CloudFront关联的Lambda函数无法获取Authorization请求头

我编写了一个Node.js 20.x版本的Lambda函数,用于控制以S3为源的CloudFront分发静态网站的访问权限。目前index.mjs中的函数始终返回401状态码,并将event结构输出到响应体中:

export const handler = async (event, context) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    return {
        status: '401',
        statusDescription: 'Unauthorized',
        body: 'Unauthorized!\n' + JSON.stringify(event),
        headers: {
            'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
        },
    };
};

问题在于,尽管浏览器已发送Authorization请求头,但该头并未出现在event中。我尝试将函数关联到"Viewer Request"和"Origin Request"事件,结果一致。两年前我曾使用完全相同的配置搭配另一组S3和CloudFront,当时可以正常工作。对比两个CloudFront分发的配置后,未发现明显差异。

如何让我的Lambda函数获取到Authorization请求头?

以下是通过aws cloudfront get-distribution-config --id=DISTRIBUTION-ID获取的分发配置:

{
    "ETag": "DISTRIBUTION-ID",
    "DistributionConfig": {
        "CallerReference": "some-uuid",
        "Aliases": {
            "Quantity": 1,
            "Items": [
                "problem.example.com"
            ]
        },
        "DefaultRootObject": "index.html",
        "Origins": {
            "Quantity": 1,
            "Items": [
                {
                    "Id": "problem.example.com.s3.us-east-1.amazonaws.com",
                    "DomainName": "problem.example.com.s3.us-east-1.amazonaws.com",
                    "OriginPath": "",
                    "CustomHeaders": {
                        "Quantity": 0
                    },
                    "S3OriginConfig": {
                        "OriginAccessIdentity": "origin-access-identity/cloudfront/OAI-ID"
                    },
                    "ConnectionAttempts": 3,
                    "ConnectionTimeout": 10,
                    "OriginShield": {
                        "Enabled": false
                    },
                    "OriginAccessControlId": ""
                }
            ]
        },
        "OriginGroups": {
            "Quantity": 0
        },
        "DefaultCacheBehavior": {
            "TargetOriginId": "problem.example.com.s3.us-east-1.amazonaws.com",
            "TrustedSigners": {
                "Enabled": false,
                "Quantity": 0
            },
            "TrustedKeyGroups": {
                "Enabled": false,
                "Quantity": 0
            },
            "ViewerProtocolPolicy": "https-only",
            "AllowedMethods": {
                "Quantity": 3,
                "Items": [
                    "HEAD",
                    "GET",
                    "OPTIONS"
                ],
                "CachedMethods": {
                    "Quantity": 3,
                    "Items": [
                        "HEAD",
                        "GET",
                        "OPTIONS"
                    ]
                }
            },
            "SmoothStreaming": false,
            "Compress": true,
            "LambdaFunctionAssociations": {
                "Quantity": 1,
                "Items": [
                    {
                        "LambdaFunctionARN": "arn:aws:lambda:us-east-1:SOME-NUMBER:function:myFunctionName:7",
                        "EventType": "viewer-request",
                        "IncludeBody": false
                    }
                ]
            },
            "FunctionAssociations": {
                "Quantity": 0
            },
            "FieldLevelEncryptionId": "",
            "ForwardedValues": {
                "QueryString": false,
                "Cookies": {
                    "Forward": "none"
                },
                "Headers": {
                    "Quantity": 1,
                    "Items": [
                        "Authorization"
                    ]
                },
                "QueryStringCacheKeys": {
                    "Quantity": 0
                }
            },
            "MinTTL": 0,
            "DefaultTTL": 60,
            "MaxTTL": 600
        },
        "CacheBehaviors": {
            "Quantity": 0
        },
        "CustomErrorResponses": {
            "Quantity": 0
        },
        "Comment": "",
        "Logging": {
            "Enabled": true,
            "IncludeCookies": false,
            "Bucket": "logging.example.com.s3.amazonaws.com",
            "Prefix": "problem"
        },
        "PriceClass": "PriceClass_100",
        "Enabled": true,
        "ViewerCertificate": {
            "CloudFrontDefaultCertificate": false,
            "ACMCertificateArn": "CERTIFICATE-ARN",
            "SSLSupportMethod": "sni-only",
            "MinimumProtocolVersion": "TLSv1.2_2021",
            "Certificate": "CERTIFICATE-ARN",
            "CertificateSource": "acm"
        },
        "Restrictions": {
            "GeoRestriction": {
                "RestrictionType": "none",
                "Quantity": 0
            }
        },
        "WebACLId": "",
        "HttpVersion": "http2",
        "IsIPV6Enabled": true,
        "ContinuousDeploymentPolicyId": "",
        "Staging": false
    }
}

解决方法

  • 确认CloudFront配置已生效:修改CloudFront缓存行为的头转发配置后,需要等待分发完成部署(状态变为Deployed),这个过程通常需要15-20分钟。如果修改后立即测试,配置可能还未生效,导致Authorization头未被转发。
  • 注意请求头的大小写转换:CloudFront会将所有请求头转换为小写形式,因此在Lambda函数中需要通过headers['authorization'](全小写)来获取,而不是headers.Authorization。这是最可能导致你看不到头的原因,修改后的示例代码如下:
    export const handler = async (event, context) => {
        const request = event.Records[0].cf.request;
        const headers = request.headers;
    
        // 用小写键获取Authorization头
        const authHeader = headers['authorization'];
        let responseBody = 'Unauthorized!\n';
        
        if (authHeader) {
            responseBody += `Authorization header detected: ${JSON.stringify(authHeader)}`;
        } else {
            responseBody += 'Authorization header not found.\n';
            responseBody += `All available headers: ${JSON.stringify(headers)}`;
        }
    
        return {
            status: '401',
            statusDescription: 'Unauthorized',
            body: responseBody,
            headers: {
                'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
            },
        };
    };
    
  • 验证浏览器实际发送的请求头:使用浏览器开发者工具的Network面板,确认请求的Request Headers中确实包含Authorization字段。部分场景下(如跨域请求),浏览器可能需要额外的CORS配置才会发送认证头。
  • 排查Lambda执行角色权限:确保Lambda@Edge的执行角色信任关系包含edgelambda.amazonaws.com,并且具备必要的Lambda执行权限。不过此问题中权限问题的可能性较低,但可作为兜底排查项。

内容的提问来源于stack exchange,提问作者Guido Flohr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 22:48:09