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

Serverless框架下AWS Lambda自定义授权器获取源IP及前置通用逻辑实现

嘿,这个问题我之前也碰到过,给你几个实用的解决方案,按优先级排序:

1. 先确认:Custom Authorizer其实能拿到源IP!

你可能没注意到,在AWS REST API的TOKEN类型Custom Authorizer中,事件对象里是包含请求源IP的,路径是event.requestContext.identity.sourceIp。

举个例子,你的Authorizer代码里可以直接这么写:

exports.handler = async (event) => {
  const token = event.authorizationToken;
  const sourceIp = event.requestContext.identity.sourceIp;

  // 1. 解析令牌,取出里面的IP/CIDR限制规则
  const decodedToken = verifyToken(token);
  const allowedIps = decodedToken.allowedIps || [];

  // 2. 验证当前请求IP是否在允许列表内
  const isIpAllowed = checkIpAgainstRules(sourceIp, allowedIps);

  if (!isIpAllowed) {
    return generatePolicy('user', 'Deny', event.methodArn);
  }

  // 验证通过,返回允许策略
  return generatePolicy('user', 'Allow', event.methodArn);
};

如果这个方法可行,那这是最贴合你现有架构的方案,不用额外改动Lambda函数,直接在Authorizer里完成所有验证。

2. 用Lambda Layer封装通用IP验证逻辑

如果因为某些场景(比如用的是HTTP API,或者Authorizer无法访问令牌里的IP规则存储)导致Authorizer拿不到IP/无法验证,那Lambda Layer是最简洁的通用逻辑复用方案:

  • 第一步:封装验证逻辑到Layer
    写一个独立的IP验证模块,比如ip-validator.js,打包成Lambda Layer:

    const cidrTools = require('cidr-tools');
    
    exports.validateIp = (allowedIps, sourceIp) => {
      const isAllowed = allowedIps.some(rule => {
        if (rule.includes('/')) {
          // 处理CIDR网段
          return cidrTools.contains(rule, sourceIp);
        } else {
          // 处理单个IP
          return rule === sourceIp;
        }
      });
    
      if (!isAllowed) {
        throw new Error('请求IP不在允许范围内');
      }
    };
    
  • 第二步:在Serverless配置中引入Layer
    给所有需要验证的Lambda函数添加Layer引用:

    service: my-api-service
    
    functions:
      getResource:
        handler: handlers/getResource.main
        layers:
          - arn:aws:lambda:us-east-1:你的账号ID:layer:IpValidator:1
        events:
          - http:
              path: resource/{id}
              method: get
              authorizer: customAuthorizer
      # 其他Lambda函数同理
    
  • 第三步:在Lambda handler中调用验证
    每个Lambda的handler开头先执行IP验证,不通过直接返回403:

    const { validateIp } = require('/opt/ip-validator');
    
    exports.main = async (event) => {
      try {
        // 从请求上下文拿源IP和Authorizer传递的令牌Claims
        const sourceIp = event.requestContext.identity.sourceIp;
        const allowedIps = event.requestContext.authorizer.allowedIps;
    
        // 执行IP验证
        validateIp(allowedIps, sourceIp);
    
        // 正常业务逻辑
        return {
          statusCode: 200,
          body: JSON.stringify('操作成功')
        };
      } catch (err) {
        return {
          statusCode: 403,
          body: JSON.stringify(err.message)
        };
      }
    };
    

3. 进阶:用Serverless插件自动注入前置逻辑

如果你的服务有很多Lambda函数,不想手动在每个handler里写验证调用,可以写一个简单的Serverless插件,在打包阶段自动给所有handler注入IP验证的代码。不过这个需要一点插件开发能力,适合大规模服务场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:08:21