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

如何使用Spring Cloud Function创建AWS Lambda自定义API Gateway授权器并正确返回策略文档

解决Spring Cloud Function Lambda授权器返回结构被包装的问题

这个问题我之前也碰到过——Spring Cloud Function的AWS适配器默认会把函数返回值包装成APIGatewayProxyResponseEvent格式(就是你看到的带isBase64Encoded、headers、body的外层结构),这是为了适配常规的API Gateway Lambda集成场景,但Lambda授权器要求直接返回策略文档JSON,不需要这层额外包装。

下面是两种可行的解决方法:

方法1:禁用代理模式包装(最快解决)

在你的Spring Boot应用配置文件(application.properties或application.yml)中添加以下配置,让AWS适配器直接返回函数的输出结果,不进行外层包装:

spring.cloud.function.adapter.aws.proxy.mode=false

配置后,你当前返回的Map<String, Object>会被直接序列化为JSON,不再被包裹到body字段里,正好符合API Gateway授权器的要求。

方法2:使用类型安全的POJO(更健壮)

如果想让代码更清晰、避免Map序列化的潜在问题,可以创建对应授权策略结构的POJO类,替换当前的Map返回:

第一步:定义AuthPolicy相关POJO

import java.util.List;
import java.util.Map;

public class AuthPolicy {
    private String principalId;
    private PolicyDocument policyDocument;
    private Map<String, Object> context;

    // Getters, Setters & Constructor
    public AuthPolicy() {}

    public AuthPolicy(String principalId, PolicyDocument policyDocument, Map<String, Object> context) {
        this.principalId = principalId;
        this.policyDocument = policyDocument;
        this.context = context;
    }

    // Getters and Setters omitted for brevity

    public static class PolicyDocument {
        private String Version = "2012-10-17";
        private List<Statement> Statement;

        // Getters, Setters & Constructor
        public PolicyDocument() {}

        public PolicyDocument(List<Statement> statement) {
            Statement = statement;
        }

        // Getters and Setters omitted for brevity
    }

    public static class Statement {
        private String Action = "execute-api:Invoke";
        private String Effect;
        private String Resource;

        // Getters, Setters & Constructor
        public Statement() {}

        public Statement(String effect, String resource) {
            Effect = effect;
            Resource = resource;
        }

        // Getters and Setters omitted for brevity
    }
}

第二步:修改Function Bean返回POJO

import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Configuration
public class AuthFunctionConfig {
    private static final Logger logger = LoggerFactory.getLogger(AuthFunctionConfig.class);

    @Bean
    public Function<APIGatewayProxyRequestEvent, AuthPolicy> authorise() {
        return request -> {
            String token = request.getHeaders().get("Authorization");
            String arn = String.format("arn:aws:execute-api:%s:%s:%s/%s/%s/",
                    System.getenv("AWS_REGION"),
                    request.getRequestContext().getAccountId(),
                    request.getRequestContext().getApiId(),
                    request.getRequestContext().getStage(),
                    request.getRequestContext().getHttpMethod());

            try {
                String effect = request.getHttpMethod().equalsIgnoreCase("GET") ? "Allow" : "Deny";
                
                // 构建Statement
                AuthPolicy.Statement statement = new AuthPolicy.Statement(effect, arn);
                // 构建PolicyDocument
                AuthPolicy.PolicyDocument policyDoc = new AuthPolicy.PolicyDocument(List.of(statement));
                // 构建上下文
                Map<String, Object> context = new HashMap<>();
                context.put("name", "test");
                
                return new AuthPolicy(UUID.randomUUID().toString(), policyDoc, context);
            } catch (Exception e) {
                logger.error("Failed to generate authorization policy", e);
                // 这里可以返回默认拒绝策略或抛出异常,根据业务需求处理
                return null;
            }
        };
    }
}

第三步:同样禁用代理模式

别忘了添加和方法1一样的配置:

spring.cloud.function.adapter.aws.proxy.mode=false

验证效果

配置完成后,你的Lambda函数返回的JSON就会是API Gateway授权器期望的结构,直接返回策略文档本身,不再有外层的包装字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 09:27:28