一、背景
新创建的Amazon API Gateway (以下简称API Gateway)的Regional级别的接口是可以通过互联网进行公开调用的。在API为应用内部调用的场景下,需要设置身份验证。主要的身份验证手段有:IAM身份验证、Lambda转发器验证(Backend可使用数据库)、OAuth/JWT认证。此外,在API Gateway上使用mTLS,配置双向证书,也可以显著提升安全性。
本文介绍如何开启IAM身份验证。
二、配置IAM身份验证
1、确认当前API Gateway的ID、接口、调用方法等信息
本文假设一个Regional类型的API Gateway接口已经创建完毕,当前是开放未设置认证的状态。
为构建IAM Policy用户授权,需要确认当前接口的信息。从Stages
位置等多个地方都可以看到API Gateway的ID,也可以看到接口名称、调用方法等信息。如下截图。
2、配置可访问API Gateway的IAM Policy
首先为要访问API Gateway的用户,创建一个最小权限的IAM Policy。在开发、测试和生产环境中,不建议使用AdministratorAccess
等具有AWS账号管理员权限的身份进行测试。因此接下来,为要访问访问API Gateway的用户(对应程序)创建专用的最小权限的IAM Policy策略。
进入IAM Policy界面,点击创建左侧Policy
,点击右侧创建Policy。如下截图。
点击第二个标签页JSON
,直接输入IAM策略,文本内容如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": [
"arn:aws-cn:execute-api:cn-northwest-1:420029960748:dmtqi47mvg/prod-iamauth/GET/pets"
]
}
]
}
请替换上一个步骤中确认的区域、AWS账户(12位数字)、API Gateway网关名称、接口名称、调用方法等信息为正确的值。
为了灵活对开发、测试、生产环境授权,IAM策略中的prod-iamauth
是代表Stages
阶段,GET
是允许的方法,pet
是Resource
。这几个字段可进行排列组合,实现授权的权限最小化管控。本例中,稍后打开了IAM授权后,还会重新部署另一个Stages
,因此Stages
阶段的名称将会从目前的prod-noauth
变化为prod-iamauth
。所以这里写IAM策略时候,直接按照新创建的名字去授权,旧的阶段不再授权。然后在要访问API Gateway的应用层进行流量切换,修改访问入口即可。
另外请注意,如果是在中国区,那么Resource
中ARN的设置应为aws-cn
,反之在Global区域则为aws
。本文档按照AWS中国区编写,因此使用aws-cn
。如下截图。
配置好IAM策略后,点击Next: Tags
按钮下一步,在标签页面可跳过,然后来到名称界面,输入本策略名称,例如APIGW-prod-get-pets
。请记住这个名称,稍后会使用这个策略。
最后点击右下角的Create policy
按钮完成创建。
2、创建IAM用户、Access Key和Secret Key
创建IAM用户、Access Key和Secret Key(以下简称AKSK)是一个标准流程,请参考IAM相应文档。本文只需要创建一个具有AWS API访问权限的用户和对应的密钥即可,不需要访问AWS控制台。因此在创建IAM用户过程中,选项Enable console access
不需要被选中。
如果您是AWS新用户,不熟悉2022年改版后的IAM操作界面,可参考这篇博客。
创建AKSK完成后将其保存好,因为IAM界面只在创建的第一次会显示完整的Secret Key,以后将不会显示。后续程序中将会使用这个AKSK测试对API Gateway的认证和访问。
3、在API Gateway上配资资源和方法,开启IAM身份验证
进入API Gateway界面,点击左侧Resource
菜单,在右侧找到要管理的资源,例如首先配置 /
目录对应的GET
方法。在页面右侧的Method Request
下方可以看到,当前配置的Auth
显示为None
,这表示当前没有打开认证。此时点击Method Request
文字链接,进入设置界面。如下截图。
在Method Execution
界面,点击Authentication
的下拉框,从刚才没有认证的None
选项,修改为Amazon IAM
。然后点击边上的对勾按钮表示保存设置。如下截图。
修改完毕后,重新回到上一步的资源界面,可以看到图中的Auth
认证已经改变,显示为Amazon IAM
。如下截图。
4、更多接口的配置(可选用AWSCLI配置)
API Gateway的资源的修改,是针对单个资源和方法的,也就是上边的截图中的对于 /
目录的GET
方法。对于其他资源和方法,依然还是处于没有认证的公开阶段,因此他们需要被逐一配置。如下截图。
逐一配置IAM认证的方法就是重复以上过程,把所有资源Resource
对应的方法Method
(即GET/POST等)逐一编辑认证选项,逐个添加。这里还提供另一种方法,可选用AWSCLI为接口批量设置。
在AWS控制台图形界面上,图中标记出来的ID就是后续要用到的资源编号。如下截图。
也通过AWSCLI查询本网关下所有的资源和方法:
aws apigateway get-resources --rest-api-id dmtqi47mvg
以上清单中,可以分别获取资源IDresource-id
和支持的方法如GET
、POST
等。
有了ID后,即可使用AWSCLI批量配置使其打开IAM认证。为单个方法配置IAM认证的命令是:
aws apigateway update-method \
--rest-api-id dmtqi47mvg \
--resource-id vlifnq \
--http-method OPTIONS \
--patch-operations op="replace",path="/authorizationType",value="AWS_IAM"
配置之后显示如下信息,其中第二行显示认证已经是IAM类型。如下截图。
重复以上过程,对所有资源和方法都执行一遍配置。
4、将开启IAM认证的配资部署为新的Stages阶段
经过确认,所有接口部署完成。接下来要将Resource
部署到Stages
推向生产。在上一步的Resource
界面,点击Actions
按钮,从下拉框中选择Deploy API
按钮,进行部署。如下截图。
在弹出的对话框中,输入要部署的Stages
的名称,这里需要与前文配置IAM Policy的授权的Stages
名称一致,这里使用prod-iamauth
。如下截图。
部署完成。回到API Gateway界面,点击左侧的Stages
按钮,可看到页面中间显示的新部署的prod-iamauth
,点击资源和方案,可看到右侧显示的Authentication
为Amazon IAM
,表示配置成功。如下截图。
至此配置部分完成。接下来进行测试。
5、AWS SignV4简介
在API Gateway打开了IAM认证后,要求客户端发送给服务器端的请求必须使用SignV4签名进行身份认证。也就是说,客户端不能直接通过CURL发送明文的AKSK到API Gateway,而是要经过HMAC-SHA256算法生成符合API Gateway要求的SignV4签名,然后带着签名才能发送到AWS云端。签名请求格式类似如下:
Authorization: AWS4-HMAC-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20220830/cn-northwest-1/execute-api/aws4_request,
SignedHeaders=host;x-amz-date,
Signature=calculated-signature
Sign V4签名才用的HMAC-SHA256算法具有足够的强度,因此经过加密的信息不会被破解。关于Sign V4的介绍,可参考本文末尾的文档。为了满足Sign V4签名的前提条件,本文后续将使用内置SignV4的客户端进行测试,并使用Python构建代码进行测试。
6、使用REST客户端软件请求
对API Gateway的请求可以通过REST客户端,例如Postman等软件。本文使用VSCode并通过THUNDER CLIENT
插件实现。
在THUNDER CLIENT插件的界面上,选择方法是GET
,输入API Gateway调用的资源地址,选择认证标签页Auth
,然后在下方输入Access Key和Secret Key。然后点击Send
按钮提交认证。此时右侧可以收到正确的请求返回信息。如下截图。
如果IAM和AKSK的认证信息不正确,则会收到错误信息。如下截图。
由此确认了带有IAM身份验证的API Gateway请求正常。
7、使用Python代码请求
Python程序调用AWS服务,包括但不限于API Gateway,需要额外安装requests
库和aws_requests_auth
。命令如下:
pip install requests aws_requests_auth -y
构建如下Python程序:
import requests
from aws_requests_auth.aws_auth import AWSRequestsAuth
# let's talk to our AWS Elasticsearch cluster
auth = AWSRequestsAuth(aws_access_key='access_key',
aws_secret_access_key='secret_key',
aws_host='dmtqi47mvg.execute-api.cn-northwest-1.amazonaws.com.cn',
aws_region='cn-northwest-1',
aws_service='execute-api')
response = requests.get('https://dmtqi47mvg.execute-api.cn-northwest-1.amazonaws.com.cn/prod-iamauth/pets',
auth=auth)
print(response.text)
以上代码不依赖于AWS Boto3 SDK,只需要构建正确的HTTP请求即可满足IAM身份认证要求的Sign V4签名。将配置信息带入后,运行程序,可看到正常返回结果。
如果IAM和AKSK的认证信息不正确,则会收到错误信息。如下截图。
由此确认了带有IAM身份验证的API Gateway请求正常。
至此所有配置过程完成。
三、参考文档
选择网关类型IAM Restful类型和HTTP类型:
https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/http-api-vs-rest.html
为API Gateway使用IAM身份验证:
https://aws.amazon.com/cn/premiumsupport/knowledge-center/iam-authentication-api-gateway/?nc1=h_ls
访问API Gateway的IAM策略最佳实践和配置样例:
通过AWSCLI为API Gateway资源和方法配置IAM认证:
https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-method.html
AWS Sign V4简介,以及常见编程语言生成Sign V4签名的Sample Code:
https://docs.aws.amazon.com/zh_cn/general/latest/gr/create-signed-request.html
Python Sign V4签名代码样例(From Github):