App Engine 应用间请求身份校验实战:基于 X-Appengine-Inbound-Appid 与 ID Token 的双通道认证
发布时间:2026/10/2 17:29:17 锦皓数字建站

示例工程【免费下载链接】python-docs-samplesCode samples used on cloud.google.com项目地址https://gitcode.com/GitHub_Trending/py/python-docs-samples点击查看免费下载导读本文基于 python-docs-samples 仓库中的 incoming 示例应用讲解如何在 App EnginePython 2.7端接收并校验来自其他 App Engine 应用的请求身份。你将掌握两套互补的调用方身份验证方案Python 2.7 调用方自带的可信X-Appengine-Inbound-Appid请求头以及 Python 3.7 调用方携带的默认服务账号 ID TokenOAuth2 Bearer。读完本文你可以直接复刻出接收端校验 发送端携带凭证的完整 App Engine 应用间安全通信闭环。背景为什么 App Engine 应用间调用需要显式身份校验在 App Engine 服务端到服务端的调用场景中一个应用调用方常常需要访问另一个 App Engine 应用被调用方暴露的接口。如果被调用方只依赖普通鉴权就无法确认请求到底来自可信的兄弟应用还是来自外部攻击者。本示例正是解决这一问题的接收端样板被调用方维护一份allowed_app_ids白名单只有当请求携带了可信身份凭证、且凭证解析出的应用 ID 在白名单内时才返回受保护的内容否则一律返回 HTTP 403。双通道校验机制两种调用方、两种凭证仓库中的 README.md 明确给出了两条校验路径Python 2.7 调用方使用urlfetch其发起的请求会携带一个由 App Engine 运行时注入、值得信任的X-Appengine-Inbound-Appid请求头。运行时会在其他请求到达应用前剥离该头因此凡是带这个头的请求其应用 ID 声明是可信的。Python 3.7 调用方不再使用urlfetch而是为调用方应用的默认服务账号获取一个 ID Token并将其放入Authorization: Bearer token请求头中。接收方通过验证该 Token 来确认调用方身份。配合使用的发送端示例是仓库中的 standard_python3/migration/urlfetch 示例应用它负责以携带合法Authorization头的方式调用本接收端应用。接收端实现逐行拆解 incoming 示例1. 目录与文件结构该示例位于 appengine/standard/migration/incoming/核心文件如下main.pyWeb 应用主逻辑包含身份解析与白名单校验app.yamlPython 2.7 运行时的 App Engine 配置appengine_config.pyvendor 库加载配置main_test.py基于 WebTest 的单元测试requirements.txt运行依赖google-auth2.17.3等requirements-test.txt测试依赖WebTest3.0.4等2. 身份解析核心函数get_app_idmain.py 中的get_app_id(request)是整套校验的关键它按优先级处理两种凭证def get_app_id(request): # 路径一Python 2.7 urlfetch 请求携带的可信头 incoming_app_id request.headers.get(X-Appengine-Inbound-Appid, None) if incoming_app_id is not None: return incoming_app_id # 路径二解析 Authorization: Bearer id_token auth_header request.headers.get(Authorization, None) if auth_header is None: return None bearer, token auth_header.split() if bearer.lower() ! bearer: return None try: info id_token.verify_oauth2_token(token, requests.Request()) service_account_email info[email] incoming_app_id, domain service_account_email.split() if domain ! appspot.gserviceaccount.com: # 非 App Engine 服务账号则拒绝 return None else: return incoming_app_id except Exception as e: logging.warning(Request has bad OAuth2 id token: {}.format(e)) return None实现要点头优先策略X-Appengine-Inbound-Appid由运行时注入且无法被伪造因此存在即直接采用无需额外验证。Bearer 解析严格性Authorization头必须严格符合Bearer token格式split()结果与bearer小写比对格式不符直接返回None。Token 验证调用id_token.verify_oauth2_token(token, requests.Request())完成签发方校验依赖google-auth库再从中取出服务账号邮箱。域名白名单校验邮箱必须形如app-idappspot.gserviceaccount.com即必须是 App Engine 默认服务账号否则拒绝。此处的domain比对是防止伪造邮箱的关键一环。异常兜底Token 过期、签名错误等情况统一捕获并记录logging.warning返回None保证接口不会因解析异常而崩溃。3. 请求处理器与白名单逻辑main.py 中的MainPage展示了完整的解析 → 校验 → 放行/拒绝链路class MainPage(webapp2.RequestHandler): allowed_app_ids [other-app-id, other-app-id-2] def get(self): incoming_app_id get_app_id(self.request) if incoming_app_id is None: self.abort(403) if incoming_app_id not in self.allowed_app_ids: self.abort(403) self.response.write(This is a protected page.) app webapp2.WSGIApplication([(/, MainPage)], debugTrue)allowed_app_ids是示例白名单实际部署时应替换为真实的调用方应用 ID即 GCP 项目 ID。两类失败凭证缺失/非法、应用 ID 不在白名单均通过self.abort(403)返回 HTTP 403。只有校验通过才输出This is a protected page.这行文本正是发送端示例回显给用户的内容。应用入口通过webapp2.WSGIApplication暴露为main.app与 app.yaml 中的script: main.app对应。4. 运行配置app.yaml 与 appengine_config.pyapp.yaml 将应用声明为 Python 2.7 标准环境runtime: python27 threadsafe: yes api_version: 1 libraries: - name: ssl version: latest handlers: - url: .* script: main.appruntime: python27表明这是迁移场景中的旧版接收端。libraries: ssl显式引入 SSL 库满足google-auth在 Python 2.7 下安全发起 HTTPS Token 校验请求的底层需求。handlers将全部路径路由到main.app。appengine_config.py 使用google.appengine.ext.vendor加载lib目录中通过pip install -t lib安装的第三方依赖如google-auth这是 Python 2.7 标准环境引入外部包的标准做法。5. 依赖清单requirements.txt 的关键依赖google-auth2.17.3 requests2.34.2; python_version 3.10google-auth提供id_token.verify_oauth2_token与google.auth.transport.requests.Request是 ID Token 校验的实现基础。发送端实现Python 3.7 调用方如何携带凭证与接收端配对的 standard_python3/migration/urlfetch 示例应用 展示了从 Python 3.7 侧获取并携带 ID Token 的完整流程from google.auth.transport import requests as reqs from google.oauth2 import id_token import requests app.route(/, methods[POST]) def make_request(): url request.form[url] token id_token.fetch_id_token(reqs.Request(), url) resp requests.get(url, headers{Authorization: fBearer {token}}) message fResponse when calling {url}:\n\n message resp.text return message, 200, {Content-type: text/plain}id_token.fetch_id_token(reqs.Request(), url)为调用方默认服务账号按目标 URL 的 audience 获取 ID Token——无需手工管理密钥或服务账号文件直接运行在 App Engine 上即可获得默认凭据。将 Token 组装为Authorization: Bearer token头后通过requests.get发起调用正好对接收端get_app_id中bearer, token auth_header.split()的解析逻辑。该应用同时提供GET /表单页templates/index.html让用户输入目标 App Engine 应用 URL 后即可测试调用响应以纯文本回显。测试验证WebTest 如何守护身份校验逻辑main_test.py 给出了针对接收端的最小可验证测试import webtest import main def test_get(): app webtest.TestApp(main.app) try: response app.get(/) assert response.status_int 403 except webtest.app.AppError as e: assert 403 Forbidden in str(e)不带任何身份头直接请求/断言返回 403——验证了无凭证一律拒绝的安全基线。测试通过webtest.TestApp(main.app)在进程内模拟 HTTP 请求无需真实部署。仓库中另有一处同源参考standard/app_identity/incoming/main_test.py 展示了携带{X-Appengine-Inbound-Appid: other-app-id}头成功访问的正面用例可与本示例的负面用例互补理解。部署与端到端使用流程部署接收端将 incoming 目录部署为 App Engine Python 2.7 应用并把真实调用方 GCP 项目 ID 填入MainPage.allowed_app_ids。部署发送端将 urlfetch 示例 部署为 Python 3.7 应用注意仓库中该路径位于appengine/standard_python3/migration/urlfetch/。发起调用在发送端表单中输入接收端应用的 URL提交后发送端获取默认服务账号的 ID Token以Authorization: Bearer头调用接收端。观察结果Token 有效且应用 ID 在白名单内时页面回显This is a protected page.凭证缺失、Token 非法或应用 ID 不在白名单时接收端返回 403。安全边界与迁移启示X-Appengine-Inbound-Appid头只能由 Python 2.7 环境的urlfetch产生App Engine 运行时会从外部请求中剥离该头因此它天然防伪造但 Python 3.7 应用不再具备该能力必须改用 ID Token 方案这正是 README 中所述替换内建可信头 的迁移要点。ID Token 校验依赖时钟同步与google-auth的公开证书校验任何校验异常都会被捕获并降级为 403属于默认拒绝的安全设计。生产环境应避免使用示例中的debugTrue并将allowed_app_ids白名单迁移到配置或环境变量管理避免硬编码。相关资源incoming README本文主文档接收端主实现接收端运行配置接收端测试Python 3.7 发送端示例app_identity 下的同源参考示例赞分享示例工程【免费下载链接】python-docs-samplesCode samples used on cloud.google.com项目地址https://gitcode.com/GitHub_Trending/py/python-docs-samples点击查看免费下载相关推荐google-api-php-client 的 ID Token 认证实战无需网络调用的用户身份校验原理与 verifyIdToken 用法google api php client 的 ID Token 认证实战无需网络调用的用户身份校验原理与 verifyIdToken 用法 导读 本文围绕后端Feathers 集成 Firebase 认证基于自定义 OAuthStrategy 校验 ID Token 的完整实战Feathers 集成 Firebase 认证基于自定义 OAuthStrategy 校验 ID Token 的完整实战 Firebase 是 Feather后端Web框架Payload JWT 认证如何签发带 role 的 JWT 并校验请求身份Payload JWT 认证如何签发带 role 的 JWT 并校验请求身份 Payload 的认证体系内置了 JWT 策略在启用认证的 Collectio后端CMS上一篇AI Toolkit性能优化GPU内存管理与训练加速技巧下一篇3步让《模拟人生1》在现代显示器上完美重生宽屏补丁完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。