使用 Lambda 创建 Authorizer 对 API Gateway 访问进行鉴权

embedded/2024/12/21 10:23:34/

背景介绍

对于配置好的 API Gateway 资源来说, 默认会允许所有客户端进行访问. 我们可以配置 API key 进行简单的访问控制, 不过需要注意, API key 主要应用场景其实还是结合 Usage plan 对访问量进行控制, 并不提供鉴权的目的. 毕竟 API key 会作为一个静态的 Header x-api-key 存在请求的 Headers 里面. 还是需要通过 Lambda 创建函数作为 Authorizer 对发往 API Gateway 的请求进行具体的鉴权操作.

Lambda 函数作为 Authorizer 有两种方式:

注: 下面的 event 表示 Lambda 接受来自 API Gateway 作为 Trigger 的事件对象

基于 Request

Request 中可以包含的信息无非也就是 Headers (event.headers), QueryString (URL 地址中包含的问号后面的 K-V 变量, event.queryStringParameters), API 的 Stage 变量 (event.stageVariables). 在 Authorizer 函数中解析这些变量并加以逻辑判断, 确认是否允许此次请求.

基于 Token

通过客户端发送请求时包含的 Bearer token 进行逻辑判断, 常用 JSON Web Token (JWT), 或者 OAuth token. Token 信息存放在 event.authorizationToken

放上官方的工作流程示意图:
在这里插入图片描述

主要工作流

当 Client 端带着 Request 参数或者 Token 发起对 API Gateway 请求后, API Gateway 将这些信息包装在 Event 中传给 Lambda Authorizer 函数进行鉴权. 结果会是一个 JSON 格式的 IAM Policy 返回给 API Gateway, 其中包含 Principal identifier (用来识别客户端身份的唯一标识). 如果 Policy 允许, 则 API Gateway 放行请求到后面的 Integration (中文叫集成, 即原本 API 设计的 Resource 目标). 反之则会直接给客户端返回 403 或者 401 响应 (可自己定义). 这里还有一个 Cache 缓存的设计, 本文暂时先不展开讨论.

Lambda authorizer 输入数据

所谓的"输入"数据, 其实就是 API Gateway 作为 Trigger 调用 Lambda 函数时发送过去的 Event 对象.

Token 方式

{"type":"TOKEN","authorizationToken":"{caller-supplied-token}","methodArn":"arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
}

Request 方式

{"type": "REQUEST","methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request","resource": "/request","path": "/request","httpMethod": "GET","headers": {"X-AMZ-Date": "20170718T062915Z","Accept": "*/*","HeaderAuth1": "headerValue1","CloudFront-Viewer-Country": "US","CloudFront-Forwarded-Proto": "https","CloudFront-Is-Tablet-Viewer": "false","CloudFront-Is-Mobile-Viewer": "false","User-Agent": "..."},"queryStringParameters": {"QueryString1": "queryValue1"},"pathParameters": {},"stageVariables": {"StageVar1": "stageValue1"},"requestContext": {"path": "/request","accountId": "123456789012","resourceId": "05c7jb","stage": "test","requestId": "...","identity": {"apiKey": "...","sourceIp": "...","clientCert": {"clientCertPem": "CERT_CONTENT","subjectDN": "www.example.com","issuerDN": "Example issuer","serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1","validity": {"notBefore": "May 28 12:30:02 2019 GMT","notAfter": "Aug  5 09:36:04 2021 GMT"}}},"resourcePath": "/request","httpMethod": "GET","apiId": "abcdef123"}
}

Lambda authorizer 输出数据

所谓"输出"数据, 即 Lambda 在进行逻辑处理之后, 最终要输出返回的数据, 其中 policyDocument 对应的是 IAM Policy 语法 JSON 内容, 除此之外还有额外的几个 Key.

{"principalId": "yyyyyyyy", // The principal user identification associated with the token sent by the client."policyDocument": {"Version": "2012-10-17","Statement": [{"Action": "execute-api:Invoke","Effect": "Allow|Deny","Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"}]},"context": {"stringKey": "value","numberKey": "1","booleanKey": "true"},"usageIdentifierKey": "{api-key}"
}

实战演练

以下实现 Request 方式的 Authorizer, 使用 AWSCLI 和 Console 进行资源的创建和配置.

REST API 创建和配置过程

创建 REST API

aws apigateway create-rest-api --name "MockAPI" --description "An API with a mock resource" --endpoint-configuration types=REGIONAL
{"id": "5g4hehluqi","name": "MockAPI","description": "An API with a mock resource","createdDate": "2024-12-17T21:28:18+08:00","apiKeySource": "HEADER","endpointConfiguration": {"types": ["REGIONAL"]},"disableExecuteApiEndpoint": false,"rootResourceId": "ck5z1k9xug"
}

获取根路径的资源 ID

aws apigateway get-resources --rest-api-id 5g4hehluqi
{"items": [{"id": "ck5z1k9xug","path": "/"}]
}

在根路径创建一个资源, 对应路径 /cip

aws apigateway create-resource --rest-api-id 5g4hehluqi --parent-id ck5z1k9xug --path-part "cip"
{"id": "qd1pk5","parentId": "ck5z1k9xug","pathPart": "cip","path": "/cip"
}

/cip 资源添加 GET 方法

aws apigateway put-method --rest-api-id 5g4hehluqi --resource-id qd1pk5 --http-method GET --authorization-type NONE
{"httpMethod": "GET","authorizationType": "NONE","apiKeyRequired": false
}

添加 Integration (集成), 访问目标 HTTP 端点

aws apigateway put-integration --rest-api-id 5g4hehluqi --resource-id qd1pk5 --http-method GET --type HTTP --integration-http-method GET --uri "http://cip.cc"
{"type": "HTTP","httpMethod": "GET","uri": "http://cip.cc","connectionType": "INTERNET","passthroughBehavior": "WHEN_NO_MATCH","timeoutInMillis": 29000,"cacheNamespace": "qd1pk5","cacheKeyParameters": []
}

设置 Method Response

aws apigateway put-method-response --rest-api-id 5g4hehluqi --resource-id qd1pk5 --http-method GET --status-code 200 --response-models '{"application/json": "Empty"}'
{"statusCode": "200","responseModels": {"application/json": "Empty"}
}

设置 Integration Response

aws apigateway put-integration-response --rest-api-id 5g4hehluqi --resource-id qd1pk5 --http-method GET --status-code 200 --selection-pattern "" --response-templates '{"application/json": "$input.body"}'
{"statusCode": "200","selectionPattern": "","responseTemplates": {"application/json": "$input.body"}
}

部署 API

aws apigateway create-deployment --rest-api-id 5g4hehluqi --stage-name dev
{"id": "7zglrj","createdDate": "2024-12-17T21:49:52+08:00"
}

测试访问

curl https://5g4hehluqi.execute-api.cn-northwest-1.amazonaws.com.cn/dev/cip/

Lambda 函数创建过程

Lambda console 创建 Python 3.13 Runtime 函数, 起名 MockAPI-Authorizer, 创建完成后记录 Function ARN arn:aws-cn:lambda:cn-northwest-1:000000000000:function:MockAPI-Authorizer

注: 以下 Python 代码由 ChatGPT 辅助生成, 基本无误一把通过

import jsondef lambda_handler(event, context):# Retrieve the 'password' from the request headerspassword = event.get('headers', {}).get('password', '')# Define the response policy based on the password valueif password == '123456':# Allow the requesteffect = 'Allow'else:# Deny the requesteffect = 'Deny'# Prepare the IAM policyprincipal_id = 'user'  # You can use a unique identifier heremethod_arn = event['methodArn']  # The ARN of the method that triggered the authorizer# Create the policy documentpolicy_document = {'Version': '2012-10-17','Statement': [{'Action': 'execute-api:Invoke','Effect': effect,'Resource': method_arn}]}# Return the policyreturn {'principalId': principal_id,'policyDocument': policy_document}

关联 API 和 Authorizer

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
更新 Resource 中的方法开启 Authorization
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

重新部署 API

aws apigateway create-deployment --rest-api-id 5g4hehluqi --stage-name dev

测试非授权访问

curl -v https://5g4hehluqi.execute-api.cn-northwest-1.amazonaws.com.cn/dev/cip/

返回 401 Unauthorized

* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 401
< date: Tue, 17 Dec 2024 15:53:51 GMT
< content-type: application/json
< content-length: 26
< x-amzn-requestid: 0df4c146-062d-4172-b398-79abd6d93336
< x-amzn-errortype: UnauthorizedException
< x-amz-apigw-id: C8W2aFST5PgEnjQ=
<
* Connection #0 to host 5g4hehluqi.execute-api.cn-northwest-1.amazonaws.com.cn left intact
{"message":"Unauthorized"}

测试授权访问

curl -v -H "password: 123456" https://5g4hehluqi.execute-api.cn-northwest-1.amazonaws.com.cn/dev/cip/

返回 200 和目标 HTTP 页面代码

* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 200
< date: Tue, 17 Dec 2024 15:55:40 GMT
< content-type: application/json
< content-length: 3314
< x-amzn-requestid: fa0270f2-65ac-4768-83cb-81db5150cb19
< x-amz-apigw-id: C8XHYGL75PgEUUA=
< x-amzn-trace-id: Root=1-67619efb-3f6c452044132b282341ff5e;Parent=34799ffb91c22252;Sampled=0;Lineage=1d8b2fdd:0
<
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>互连协议查询 - IP查询 - 查IP(www.cip.cc)</title>...省略...

http://www.ppmy.cn/embedded/147505.html

相关文章

方正畅享全媒体新闻采编系统 screen.do SQL注入漏洞复现

0x01 产品简介 方正畅享全媒体新闻生产系统是以内容资产为核心的智能化融合媒体业务平台,融合了报、网、端、微、自媒体分发平台等全渠道内容。该平台由协调指挥调度、数据资源聚合、融合生产、全渠道发布、智能传播分析、融合考核等多个平台组成,贯穿新闻生产策、采、编、发…

【功能安全】硬件架构度量

目录 01 硬件架构度量介绍 02 硬件架构度量相关说明 03 硬件架构度量示例 04 硬件架构度量模板 01 硬件架构度量介绍 GBT 34590 2022 part5

网络协议与网络安全学习记录

SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全&#xff08;Transport Layer Security&#xff0c;TLS&#xff09;是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密 HTTPS,代表Hyper Text Transfer Protocol Secure,将SSL/T…

一款轻量级的开源笔记服务软件

大家好&#xff0c;我是兔兔&#xff0c;一位写作爱好者&#xff0c;今天分享的内容是&#xff0c;如何搭建一个开源的、隐私优先的轻量级笔记服务应用。 不知道大家是否有这样的需求&#xff1a; 1、自己想搭建一个个人的学习笔记文档&#xff0c;既要自己看也可以单独分享给…

WebRTC搭建与应用(一)-ICE服务搭建

WebRTC搭建与应用(一) 近期由于项目需要在研究前端WebGL渲染转为云渲染&#xff0c;借此机会对WebRTC、ICE信令协议等有了初步了解&#xff0c;在此记录一下&#xff0c;以防遗忘。 第一章 ICE服务搭建 文章目录 WebRTC搭建与应用(一)前言一、ICE是什么&#xff1f;二、什么…

XML Schema 复合类型 - 混合内容

XML Schema 复合类型 - 混合内容 XML Schema 是一种用于定义 XML 文档结构和内容的语言。在 XML Schema 中&#xff0c;复合类型是一种包含其他元素和/或属性的复杂类型。混合内容&#xff08;Mixed Content&#xff09;是复合类型的一种特殊形式&#xff0c;它允许元素包含其…

MCP技术与Cline集成指南:打造智能AI助手的数据连接解决方案

引言 Model Context Protocol&#xff08;MCP&#xff09;是由Anthropic推出的一种全新开放标准&#xff0c;旨在为AI助手提供与数据源之间的安全连接能力。通过MCP技术&#xff0c;开发者可以实现AI助手与内容存储库、业务工具和开发环境的无缝集成&#xff0c;从而帮助前沿模…

零基础学安全--wireshark简介

目录 主要功能 捕获网络数据包 协议解析 数据包分析 数据包重组 过滤功能 统计与图表功能 官网 Wireshark是一个开源的网络协议分析工具 主要功能 捕获网络数据包 能够实时捕获网络中传输的数据包&#xff0c;用户选择要监听的网络接口&#xff08;如以太网、WiFi等…