如何用AWS API Gateway+Cognito结合Site-to-Site VPN暴露本地K8s API并授权?
方案实现指南:通过HTTP API Gateway+AWS Cognito暴露本地K8s API并实现权限控制
一、环境现状
本地K8s API路由
10.100.0.200/status 10.100.0.200/delete 10.100.0.200/create
AWS VPC与VPN连通状态
已完成以下配置:
- 公有子网关联互联网网关,私有子网关联虚拟网关
- Site-to-Site VPN绑定至虚拟网关,本地路由已对AWS可见
- 可通过公有子网EC2跳转至私有子网EC2访问本地API,测试示例:
[ec2-user@ip-10-250-2-99 ~]$ ssh ec2-user@10.250.1.99 -i ec2-deployer-key [ec2-user@ip-10-250-1-99 ~]$ curl http://10.100.0.200/delete {"message":"this is the delete route"}
二、核心需求
- 用AWS Cognito管理API用户认证
- 细粒度路由权限控制:
- 所有认证用户可访问
/status - 部分用户可访问
/delete,部分可访问/create - 部分用户可访问全部路由
- 所有认证用户可访问
- 将Cognito用户自定义属性(如
role: engineer)传递至本地API的请求负载中
三、分步实现方案
结合你的思路,补充具体操作细节:
1. 创建VPC Link打通HTTP API Gateway与私有子网
- 直接在API Gateway控制台创建VPC Link,选择关联绑定了虚拟网关的私有子网
- 确保VPC Link的安全组允许API Gateway的服务IP访问私有子网内可触达本地K8s API的网络端口(默认HTTP用80端口)
- 后续HTTP API的路由目标都指向这个VPC Link,通过它转发请求到本地10.100.0.200的API端点
2. 配置AWS Cognito实现认证与细粒度权限
2.1 创建用户池与用户组
- 创建Cognito用户池,启用JWT认证,配置应用客户端(用于用户登录获取令牌)
- 创建4个用户组对应不同权限:
all-access-group:可访问所有路由delete-access-group:仅可访问/deletecreate-access-group:仅可访问/createstatus-only-group:仅可访问/status(作为兜底组,覆盖默认可访问/status的用户)
- 为每个组绑定对应的IAM角色,角色需包含允许调用对应API Gateway路由的权限策略,示例(
delete-access-group的角色策略):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:你的区域:你的账号ID:API Gateway ID/*/DELETE/delete" }, { "Effect": "Allow", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:你的区域:你的账号ID:API Gateway ID/*/GET/status" } ] }
- 用户可加入多个组,权限会自动叠加
2.2 配置自定义用户属性
- 在Cognito用户池的属性配置里,添加自定义属性
role(字符串类型),允许用户或管理员设置该属性 - 确保用户池的ID Token或Access Token配置中包含这个自定义属性,这样令牌里会携带
role字段
3. 配置HTTP API Gateway
3.1 创建路由与集成
- 创建HTTP API,分别添加三个路由:
GET /status、POST /delete、POST /create(根据你的API实际请求方法调整) - 每个路由的集成目标选之前创建的VPC Link,集成端点设为
http://10.100.0.200/对应路由,比如/status对应http://10.100.0.200/status
3.2 配置授权与请求转换
- 为所有路由启用Cognito JWT授权器,关联之前创建的用户池,只有携带有效Cognito令牌的请求才能通过认证
- 在API Gateway的路由级别配置IAM权限,结合Cognito组绑定的IAM角色,实现不同组的用户只能访问对应路由
- 配置请求转换模板,把Cognito令牌中的自定义属性(比如
role)提取出来,添加到转发给本地API的请求头里。例如,在集成请求的Headers中添加:X-User-Role: $context.authorizer.claims.role
这样本地API就能从请求头拿到用户的role属性
4. 验证方案
- 创建不同组的测试用户,给部分用户设置自定义
role属性 - 用测试用户获取Cognito JWT令牌,调用API Gateway的对应路由,验证权限是否符合预期
- 检查本地API收到的请求,确认
role属性已被正常传递
内容的提问来源于stack exchange,提问作者dvidg
相关产品推荐
相关产品推荐

