写点什么

使用 Amazon Verified Permissions 快速为 Express 应用 API 添加安全防护

作者:qife122
  • 2025-08-27
    福建
  • 本文字数:7679 字

    阅读完需:约 25 分钟

使用 Amazon Verified Permissions 在几分钟内保护您的 Express 应用 API

今天,Amazon Verified Permissions 发布了 @verifiedpermissions/authorization-clients-js,这是一个开源包,开发人员可以在使用 Verified Permissions 时,用它为 Express.js Web 应用 API 快速实现外部细粒度授权。


Express 是一个极简且灵活的 Node.js Web 应用框架,为 Web 和移动应用提供了一套强大的功能。通过使用这种与 Verified Permissions 的标准化集成,开发人员可以用比编写自定义集成少 90%的代码外部化授权,节省时间和精力,并通过减少自定义集成代码量来提升应用安全状况。

为什么要外部化授权?

传统上,开发人员通过将授权逻辑直接嵌入应用代码中来实现授权。这种嵌入式授权逻辑设计用于支持少量权限,但随着应用的发展,通常需要逐步更新嵌入式授权逻辑以支持更复杂的用例,导致代码复杂且难以维护。随着代码复杂性的增加,进一步演进安全模型和执行权限审计变得更加困难,导致应用在其生命周期中越来越难以维护。


通过外部化授权,您可以将授权逻辑与应用解耦。这带来了多重好处,包括解放开发团队专注于应用逻辑,并简化软件审计。

使用 Cedar 外部化授权

一种从应用代码外部化授权的方法是使用 Cedar。Cedar 是一种开源语言和软件开发工具包(SDK),用于编写和执行应用的授权策略。您可以将细粒度权限指定为 Cedar 策略,应用通过调用 Cedar SDK 来授权访问请求。例如,如果您正在构建一个宠物商店应用,可以使用以下 Cedar 策略来控制只有 jobLevel 为 employee 的用户才能访问 POST /pets API。


permit (    principal,    action in [Action::"POST /pets"],     resource) when {    principal.jobLevel = "employee"};
复制代码


使用 Cedar 的一种选项是自我管理实现;您可以在另一篇文章中找到此模式的示例:使用Cedar在5分钟内保护您的应用API


自我管理的 Cedar 提供了外部化授权的好处,但需要持续的操作管理。组织负责 Cedar 版本升级、应用安全补丁、管理策略和审计授权。使用 Cedar 的另一种选项是使用 Verified Permissions。Verified Permissions 通过提供 Cedar 的托管服务来消除这些操作需求。Verified Permissions 管理扩展,通过支持集中策略管理简化策略治理,并记录策略更改和授权请求以简化审计。

集成 Verified Permissions 到 Express 应用

本文描述了 Web 应用开发人员如何使用新的 Express 包来简化 Express Web 应用与 Verified Permissions 的集成。分步指南使用一个示例宠物商店应用来展示如何基于用户组限制 API 访问。您可以在 GitHub 上的 verifiedpermissions 存储库中找到示例宠物商店应用。

宠物商店应用 API 概述

宠物商店应用用于管理宠物商店。该宠物商店使用 Express 与 Node.js 构建,并暴露了下表中的 API。



该应用不允许所有用户访问所有 API。相反,它强制执行以下规则:


  • 管理员:对宠物和管理功能的完全访问权限

  • 员工:可以查看、创建和更新宠物

  • 客户:可以查看宠物和创建新宠物

实现宠物商店 API 的授权

让我们逐步介绍如何使用 Verified Permissions 和新的 Express 包来保护您的应用 API。初始应用(无授权)可以在 start 文件夹中找到;使用它来跟随本文。您可以在 finish 文件夹中找到应用的完成版本。


完成后,您将实现图 1 中所示的应用架构。一个使用 Amazon Cognito 进行身份验证的 React 前端应用。然后,应用将 Cognito 返回的身份令牌作为授权头包含到 Express 后端 API 中。Express 后端使用新的 Verified Permissions 授权中间件包调用 Verified Permissions 来授权用户请求。

先决条件

在开始之前,请确保满足以下先决条件。

步骤 1:设置 AWS CLI

某些命令需要 AWS 命令行界面(AWS CLI)。请参阅安装或更新到最新版本的AWS CLI配置AWS CLI设置

步骤 2:设置 OpenID Connect 身份提供者和数据库

宠物商店应用使用 OpenID Connect(OIDC)身份提供者来管理用户。对于此示例,您使用名为 PetStoreUserPool 的 Amazon Cognito 用户池,其中包含三个用户:一个管理员、一个员工和一个客户。


该应用还使用 Amazon DynamoDB 数据库来存储宠物。


您可以通过在/start 目录中运行以下命令在 AWS 账户中设置 Amazon Cognito 和 DynamoDB。


./scripts/setup-infrastructure.sh
复制代码


设置脚本将提示您为三个用户设置密码(密码必须至少 8 个字符,并需要至少一个数字、一个大写字母和一个小写字母)。


注意运行此脚本的输出,因为您将在“集成 Verified Permissions”的步骤 5 中使用它们。


注意:在您自己的应用中,您可以按照在Amazon Cognito控制台中创建新应用的说明设置 Amazon Cognito,或者您可以自带 OIDC 身份提供者。

步骤 3(可选):运行应用

现在基础设施已设置,您可以运行应用。在两个单独的终端中,在/start 目录中运行以下命令:


./scripts/run-backend-dev.sh./scripts/run-frontend-dev.sh
复制代码


通过创建一些宠物来测试应用。

集成 Verified Permissions

先决条件就绪后,下一步是集成 Verified Permissions。Verified Permissions 可以通过六个步骤集成到 Express 应用中:


  1. 创建 Verified Permissions 策略存储

  2. 添加 Cedar 和 Verified Permissions 授权中间件包

  3. 创建和部署 Cedar 模式

  4. 创建和部署 Cedar 策略

  5. 将 Verified Permissions 策略存储连接到您的 OIDC 身份提供者

  6. 更新应用代码以调用 Verified Permissions 来授权 API 访问


Verified Permissions 集成发生在 Express Web 应用后端。本节中的所有命令都应在/start/backend 目录中运行。

步骤 1:创建 Verified Permissions 策略存储

使用 AWS CLI 通过运行以下命令在 Verified Permissions 中创建策略存储。


aws verifiedpermissions create-policy-store --validation-settings "mode=STRICT"
复制代码


示例成功命令输出:


{    "policyStoreId": "AAAAbbbbCCCCdddd",    "arn": "arn:aws:verifiedpermissions::111122223333:policy-store/AAAAbbbbCCCCdddd",    "createdDate": "2025-06-05T19:30:37.896119+00:00",    "lastUpdatedDate": "2025-06-05T19:30:37.896119+00:00"}
复制代码


保存命令输出中的 policyStoreId 值以在步骤 3 中使用。

步骤 2:添加 Cedar 和 Verified Permissions 授权中间件包

运行以下命令以添加两个新依赖项:@verifiedpermissions/authorization-clients-js 和 @cedar-policy/authorization-for-expressjs。


npm i --save @verifiedpermissions/authorization-clients-jsnpm i --save @cedar-policy/authorization-for-expressjs
复制代码

步骤 3:创建和部署 Cedar 模式

Cedar 模式定义了应用的授权模型,包括应用中的实体类型和允许用户执行的操作。您将模式附加到 Verified Permissions 策略存储,当策略被添加或修改时,服务会自动根据模式验证策略。


@cedar-policy/authorization-for-expressjs 包可以分析应用的 OpenAPI 规范并生成 Cedar 模式。具体来说,您的规范中需要 OpenAPI 模式中的 paths 对象。


如果您没有 OpenAPI 规范,可以使用您选择的工具生成一个。有几个开源库可以用于 Express;您可能需要向应用添加一些代码,生成 OpenAPI 规范,然后删除代码。或者,一些基于生成式 AI 的工具,如 Amazon Q Developer CLI,可以有效地生成 OpenAPI 规范文档。无论您如何生成规范,请确保验证工具的正确输出。


对于示例应用,已包含一个名为 openapi.json 的 OpenAPI 规范文档。


运行以下命令生成 Cedar 模式。


npx @cedar-policy/authorization-for-expressjs generate-schema --api-spec schemas/openapi.json --namespace PetStoreApp --mapping-type SimpleRest
复制代码


示例成功命令输出:


Cedar schema successfully generated. Your schema files are named: v2.cedarschema.json, v4.cedarschema.json.v2.cedarschema.json is compatible with Cedar 2.x and 3.xv4.cedarschema.json is compatible with Cedar 4.x and required by the nodejs Cedar plugins.
复制代码


接下来,格式化 Cedar 模式以与 AWS CLI 一起使用。所需的特定格式在Amazon Verified Permissions策略存储模式文档中描述。要格式化 Cedar 模式,请运行以下命令。


../scripts/prepare-cedar-schema.sh v2.cedarschema.json v2.cedarschema.forAVP.json
复制代码


示例成功命令输出:


Cedar schema prepared successfully: v2.cedarschema.forAVP.jsonYou can now use it with AWS CLI:
复制代码


模式格式化后,运行以下命令将模式上传到 Verified Permissions。注意,您需要将<policy store id>替换为实际的策略存储 ID,该 ID 由步骤 1 中的命令输出提供。


aws verifiedpermissions put-schema --definition file://v2.cedarschema.forAVP.json --policy-store-id <policy store id>
复制代码


示例成功命令输出:


{    "policyStoreId": "AAAAbbbbCCCCdddd",    "namespaces": [        "PetStoreApp"    ],    "createdDate": "2025-06-03T20:19:33.480528+00:00",    "lastUpdatedDate": "2025-06-05T19:42:45.198325+00:00"}
复制代码

步骤 4:创建和部署 Cedar 策略

如果未配置任何策略,Cedar 会拒绝授权请求。下一步是创建策略,这些策略将允许特定用户组访问特定资源。Express 框架集成通过基于先前生成的模式生成示例策略来帮助引导此过程。然后,您可以根据您的用例自定义这些策略。


运行以下命令生成示例 Cedar 策略。


npx @cedar-policy/authorization-for-expressjs generate-policies --schema v2.cedarschema.json
复制代码


示例成功命令输出:


Cedar policy successfully generated in policies/policy_1.cedarCedar policy successfully generated in policies/policy_2.cedar
复制代码


两个示例策略在/policies 目录中生成:policy_1.cedar 和 policy_2.cedar。policy_1.cedar 为 admin 用户组中的用户提供对任何资源执行任何操作的权限。


// policy_1.cedar// Allows admin usergroup access to everythingpermit (    principal in PetStoreApp::UserGroup::"admin",    action,    resource);
复制代码


policy_2.cedar 为 Cedar 模式中定义的单个操作提供更多访问权限,并为特定组提供了占位符。


// policy_2.cedar// Allows more granular user group control, change actions as neededpermit (    principal in PetStoreApp::UserGroup::"ENTER_THE_USER_GROUP_HERE",    action in        [PetStoreApp::Action::"GET /pets",         PetStoreApp::Action::"POST /pets",         PetStoreApp::Action::"GET /pets/{petId}",         PetStoreApp::Action::"PUT /pets/{petId}",         PetStoreApp::Action::"DELETE /pets/{petId}"],    resource);
复制代码


注意,如果您在 OpenAPI 规范中指定了 operationId,则 Cedar 模式中定义的操作名称将使用该 operationId,而不是默认的<HTTP Method> /<PATH>格式。在这种情况下,请确保 Cedar 策略中的操作命名与 Cedar 模式中的操作命名匹配。例如,如果您想将操作称为 AddPet 而不是 POST /pets,您可以将 OpenAPI 规范中的 operationId 设置为 AddPet。Cedar 策略中的结果操作将是 PetStoreApp::Action::"AddPet"。


创建第三个策略文件,名为 policy_3.cedar,然后将每个文件的内容替换为以下策略。将每个策略中的<userpoolId>替换为之前复制的 Cognito 用户池 ID。


注意:在实际用例中,考虑根据内容重命名 Cedar 策略文件,例如 allow_customer_group.cedar。


// Defines permitted administrator user group actionspermit (    principal in PetStoreApp::UserGroup::"<userPoolId>|administrator",    action,    resource);
// Defines permitted employee user group actionspermit ( principal in PetStoreApp::UserGroup::"<userPoolId>|employee", action in [PetStoreApp::Action::"GET /pets", PetStoreApp::Action::"POST /pets", PetStoreApp::Action::"GET /pets/{petId}", PetStoreApp::Action::"PUT /pets/{petId}"], resource);
// Defines permitted customer user group actionspermit ( principal in PetStoreApp::UserGroup::"<userPoolId>|customer", action in [PetStoreApp::Action::"GET /pets", PetStoreApp::Action::"POST /pets", PetStoreApp::Action::"GET /pets/{petId}"], resource);
复制代码


策略需要格式化以便与 AWS CLI for Verified Permissions 一起使用。特定格式在AWS CLI Verified Permissions文档中描述。运行以下命令格式化策略。


../scripts/convert_cedar_policies.sh
复制代码


示例成功命令输出:


Converting policies/policy_1.cedar to policies/json/policy_1.jsonCreated policies/json/policy_1.jsonConverting policies/policy_2.cedar to policies/json/policy_2.jsonCreated policies/json/policy_2.jsonConverting policies/policy_3.cedar to policies/json/policy_3.jsonCreated policies/json/policy_3.jsonConversion complete. JSON policy files are in ../policies/json/
复制代码


格式化后的策略将输出到 backend/policies/json/目录。


格式化策略后,运行以下三个命令,每个策略一个,将它们上传到 Verified Permissions。策略存储 ID 在完成步骤 2 后返回。将<policy store id>替换为实际的策略存储 ID。


aws verifiedpermissions create-policy --definition file://policies/json/policy_1.json --policy-store-id <policy store id>aws verifiedpermissions create-policy --definition file://policies/json/policy_2.json --policy-store-id <policy store id>aws verifiedpermissions create-policy --definition file://policies/json/policy_3.json --policy-store-id <policy store id>
复制代码


示例成功命令输出:


{    "policyStoreId": "AAAAbbbbCCCCdddd",    "policyId": "8AmzZYMw6Ux5DGBoX7w24m",    "policyType": "STATIC",    "principal": {        "entityType": "PetStoreApp::UserGroup",        "entityId": "<userPoolId>|administrator"    },    "createdDate": "2025-06-05T19:46:45.848602+00:00",    "lastUpdatedDate": "2025-06-05T19:46:45.848602+00:00",    "effect": "Permit"}
复制代码


或者,您也可以在 AWS 管理控制台中将 Cedar 策略复制并粘贴到 Verified Permissions 中。

步骤 5:将 Verified Permissions 策略存储连接到您的 OIDC 身份提供者

默认情况下,Verified Permissions 授权器中间件读取 API 请求的授权头中提供的 JSON Web 令牌(JWT)以获取用户信息。Verified Permissions 可以验证令牌,并执行授权策略评估。


为此,在 Verified Permissions 策略存储中创建身份源。为了简化 AWS CLI 命令中的格式化,我们已在 identity-source-configuration.txt 中定义了身份源配置。根据运行先决条件步骤 2 中的 setup-infrastructure.sh 脚本的输出,替换以下代码块中的<userPoolArn>和<clientId>参数。


// identity-source-configuration.txt{    "cognitoUserPoolConfiguration": {        "userPoolArn": "<userPoolArn>",        "clientIds":["<clientId>"] ,        "groupConfiguration": {              "groupEntityType": "PetStoreApp::UserGroup"        }    }}
复制代码


更新文件后,运行以下命令更新 Verified Permissions 策略存储。将<policy store id>替换为实际的策略存储 ID。


aws verifiedpermissions create-identity-source --configuration file://identity-source-configuration.txt --policy-store-id <policy store id> --principal-entity-type PetStoreApp::User
复制代码


示例成功命令输出:


{    "createdDate": "2025-06-05T20:02:53.992782+00:00",    "identitySourceId": "DTLvwdiKfdPmk2RWzSVfu2",    "lastUpdatedDate": "2025-06-05T20:02:53.992782+00:00",    "policyStoreId": "AAAAbbbbCCCCdddd"}
复制代码

步骤 6:更新应用代码以调用 Verified Permissions 来授权 API 访问

您现在需要更新应用以使用 @verifiedpermissions/authorization-clients-js 和 @cedar-policy/authorization-for-expressjs 依赖项。这将允许应用调用 Verified Permissions 来授权 API 请求。


通过将以下代码块添加到 backend/app.ts 的第 13 行(直接在 import 语句之后)来添加依赖项并定义 CedarAuthorizerMiddleware 和 AVPAuthorizer。将以下代码块中的<policystoreId>替换为您的实际 Verified Permissions 策略存储 ID。


const { ExpressAuthorizationMiddleware } = require('@cedar-policy/authorization-for-expressjs');
const { AVPAuthorizationEngine } = require('@verifiedpermissions/authorization-clients-js');
const avpAuthorizationEngine = new AVPAuthorizationEngine({ policyStoreId: <policyStoreId>, callType: 'identityToken'});
const expressAuthorization = new ExpressAuthorizationMiddleware({ schema: { type: 'jsonString', schema: fs.readFileSync(path.join(__dirname, '../v4.cedarschema.json'), 'utf8'), }, authorizationEngine: avpAuthorizationEngine, principalConfiguration: { type: 'identityToken' }, skippedEndpoints: [], logger: { debug: (s: any) => console.log(s), log: (s: any) => console.log(s), }});
复制代码


配置 Express 应用以使用您刚刚定义的授权中间件。为此,在 app.use(..)语句块之后添加以下代码行,该语句块在注释// Configure security and performance middleware 之后开始(大约第 48 行,具体取决于您如何粘贴先前的代码块)。


app.use(expressAuthorization.middleware);
复制代码


您现在已成功在应用中设置授权,通过创建 Verified Permissions 策略存储、编写 Cedar 策略来定义授权,并将应用与 Verified Permissions 集成。

验证 API 安全性

您可以使用前端 Web 应用来验证授权是否已应用于 API。在两个单独的终端中,在/start 目录中运行以下命令。


./scripts/run-backend-dev.sh./scripts/run-frontend-dev.sh
复制代码


在浏览器中导航到 http://localhost:3001,并使用您之前创建的 Amazon Cognito 用户之一登录。验证权限策略是否按预期工作:


  • 管理员:可以查看、创建、更新和删除宠物。

  • 员工:可以查看、创建和更新宠物。

  • 客户:可以查看宠物和创建新宠物。


在 Express 应用的终端中,您可以看到提供授权决策额外详细信息的日志输出。例如,在未经授权的操作之后,终端输出以下内容:


Authorization result: {"type":"deny"}
复制代码

结论

新的 @verifiedpermissions/authorization-clients-js 包允许 Express 开发人员将其应用与 Verified Permissions 集成,以将授权逻辑与代码解耦。通过解耦授权逻辑并将应用与 Verified Permissions 集成,您可以提高开发人员生产力并简化权限和访问审计。


为了支持在编写 Cedar 策略时分析和审计权限,开源 Cedar 项目最近还开源了 Cedar Analysis CLI,以帮助开发人员对其策略执行策略分析。您可以在Introducing Cedar Analysis: Open Source Tools for Verifying Authorization Policies中了解有关此新工具的更多信息。


框架包是开源的,可在 GitHub 上根据 Apache 2.0 许可证获得,并通过 NPM 分发。要了解更多信息,请参阅Amazon Verified PermissionsCedar


如果您对此帖子有反馈,请在下面的评论部分提交评论。更多精彩内容 请关注我的个人公众号 公众号(办公 AI 智能小助手)公众号二维码


办公AI智能小助手


用户头像

qife122

关注

还未添加个人签名 2021-05-19 加入

还未添加个人简介

评论

发布
暂无评论
使用Amazon Verified Permissions快速为Express应用API添加安全防护_qife122_InfoQ写作社区