

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将 Express 与亚马逊验证权限集成
<a name="integration-express"></a>

Verified Permissions Express 集成提供了一种基于中间件的方法来在 Express.js 应用程序中实现授权。通过这种集成，您可以使用精细的授权策略保护您的 API 端点，而无需修改现有的路由处理程序。该集成通过拦截请求、根据您定义的策略对其进行评估并确保只有授权用户才能访问受保护的资源来自动处理授权检查。

本主题将引导您完成设置 Express 集成，从创建策略存储到实施和测试授权中间件。通过执行这些步骤，您只需最少的代码更改即可向 Express 应用程序添加强大的授权控件。

本主题中引用了以下GitHub存储库：
+ [cedar-policy/ authorization-for-expressjs-Express.js](https://github.com/cedar-policy/authorization-for-expressjs) 的 Cedar 授权中间件
+ veri@@ [fiedpermissions/ authorization-clients-js-的已验证权限授权](https://github.com/verifiedpermissions/authorization-clients-js)客户端 JavaScript
+ [verifiedpermissions/examples/express-petstore](https://github.com/verifiedpermissions/examples/tree/main/express-petstore)-使用 Express.js 中间件的示例实现

## 先决条件
<a name="express-integration-prerequisites"></a>

在实施 Express 集成之前，请确保：
+ 有权访问已验证权限的[AWS 账户](https://docs.aws.amazon.com/accounts/latest/reference/getting-started.html)
+ [Node.js](https://nodejs.org/) 和 [npm 安装](https://docs.npmjs.com/)了
+ 一个 [Express.js](https://expressjs.com/) 应用程序
+ OpenID Connect (OIDC) 身份提供商（例如）[Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html)
+ [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html)配置了适当的权限

## 设置集成
<a name="express-integration-setup"></a>

### 步骤 1：创建策略存储
<a name="setup-create-policy-store"></a>

使用以下方法创建策略存储 AWS CLI：

```
aws verifiedpermissions create-policy-store --validation-settings "mode=STRICT"
```

**注意**  
保存响应中返回的策略存储 ID，以便在后续步骤中使用。

### 步骤 2：安装依赖关系
<a name="setup-install-dependencies"></a>

在您的 Express 应用程序中安装所需的软件包：

```
npm i --save @verifiedpermissions/authorization-clients-js
npm i --save @cedar-policy/authorization-for-expressjs
```

## 配置授权
<a name="express-integration-configuration"></a>

### 步骤 1：生成并上传 Cedar 架构
<a name="config-generate-cedar-schema"></a>

架构定义了应用程序的授权模型，包括应用程序中的实体类型和允许用户执行的操作。我们建议为架构定义[命名空间](https://docs.cedarpolicy.com/overview/terminology.html#term-namespaces)。在此示例中，我们使用的是 `YourNamespace`。您将架构附加到已验证权限策略存储中，当添加或修改策略时，该服务会自动根据架构验证策略。

该`@cedar-policy/authorization-for-expressjs`软件包可以分析您的应用程序的 [OpenAPI 规格](https://swagger.io/specification/)并生成 Cedar 架构。具体而言，路径对象在您的规范中是必需的。

如果您没有 OpenAPI 规范，则可以按照[express-openapi-generator](https://github.com/nklisch/express-openapi-generator)软件包的快速说明生成 OpenAPI 规范。

根据你的 OpenAPI 规范生成一个架构：

```
npx @cedar-policy/authorization-for-expressjs generate-schema --api-spec schemas/openapi.json --namespace YourNamespace --mapping-type SimpleRest
```

接下来，格式化 Cedar 架构以便与一起使用 AWS CLI。有关所需特定格式的更多信息，请参阅[Amazon Verified Permissions 策略存储架构](schema.md)。如果你需要格式化架构方面的帮助，可以在[已验证的权限](https://github.com/verifiedpermissions/examples/tree/main/express-petstore/start/scripts) GitHub /示例存储库`prepare-cedar-schema.sh`中调用一个名为的脚本。以下是对该脚本的调用示例，该脚本在`v2.cedarschema.forAVP.json`文件中输出已验证权限格式的架构。

```
./scripts/prepare-cedar-schema.sh v2.cedarschema.json v2.cedarschema.forAVP.json
```

将格式化的架构上传到您的策略存储区，`policy-store-id`替换为您的策略存储 ID：

```
aws verifiedpermissions put-schema \
  --definition file://v2.cedarschema.forAVP.json \
  --policy-store-id policy-store-id
```

### 步骤 2：创建授权策略
<a name="config-create-authorization-policies"></a>

如果未配置任何策略，Cedar 将拒绝所有授权请求。Express 框架集成通过根据先前生成的架构生成示例策略来帮助启动此过程。

在生产应用程序中使用此集成时，我们建议使用基础设施即代码 (IaaC) 工具创建新策略。有关更多信息，请参阅 [使用创建 Amazon 已验证的权限资源 AWS CloudFormation](cloudformation-verified-permissions.md)。

生成 Cedar 策略示例：

```
npx @cedar-policy/authorization-for-expressjs generate-policies --schema v2.cedarschema.json
```

这将在`/policies`目录中生成示例策略。然后，您可以根据自己的用例自定义这些策略。例如：

```
// Defines permitted administrator user group actions
permit (
    principal in YourNamespace::UserGroup::"<userPoolId>|administrator",
    action,
    resource
);

// Defines permitted employee user group actions
permit (
    principal in YourNamespace::UserGroup::"<userPoolId>|employee",
    action in
        [YourNamespace::Action::"GET /resources",
         YourNamespace::Action::"POST /resources",
         YourNamespace::Action::"GET /resources/{resourceId}",
         YourNamespace::Action::"PUT /resources/{resourceId}"],
    resource
);
```

格式化策略以便与一起使用 AWS CLI。*有关所需格式的更多信息，请参阅参考资料中的 [create-pol](https://docs.aws.amazon.com/cli/latest/reference/verifiedpermissions/create-policy.html) icy。AWS CLI *如果你在格式化策略时需要帮助，可以在[已验证的权限](https://github.com/verifiedpermissions/examples/tree/main/express-petstore/start/scripts) GitHub /示例存储库`convert_cedar_policies.sh`中有一个名为的脚本。以下是对该脚本的调用：

```
./scripts/convert_cedar_policies.sh
```

将格式化的策略上传到 Verified Per `policy_1.json` missions，替换为策略文件的路径和`policy-store-id`名称以及您的策略存储库 ID：

```
aws verifiedpermissions create-policy \
  --definition file://{{policies/json/policy_1.json}} \
  --policy-store-id policy-store-id
```

### 步骤 3：连接身份提供商
<a name="config-connect-identity-provider"></a>

默认情况下，经过验证的权限授权中间件会读取 API 请求的授权标头中提供的 JSON Web 令牌 (JWT)，以获取用户信息。除了执行授权策略评估外，已验证权限还可以验证令牌。

使用您的`userPoolArn`和创建一个名为的身份源配置文件`identity-source-configuration.txt`，该文件如下所示`clientId`：

```
{
    "cognitoUserPoolConfiguration": {
        "userPoolArn": "arn:aws:cognito-idp:region:account:userpool/pool-id",
        "clientIds": ["client-id"],
        "groupConfiguration": {
            "groupEntityType": "YourNamespace::UserGroup"
        }
    }
}
```

通过运行以下 AWS CLI 命令创建身份源，`policy-store-id`替换为您的策略存储 ID：

```
aws verifiedpermissions create-identity-source \
  --configuration file://identity-source-configuration.txt \
  --policy-store-id policy-store-id \
  --principal-entity-type YourNamespace::User
```

## 实现授权中间件
<a name="express-integration-implementing-middleware"></a>

更新您的 Express 应用程序以包含授权中间件。在此示例中，我们使用的是身份令牌，但您也可以使用访问令牌。有关更多信息，请参阅[authorization-for-expressjs](https://github.com/cedar-policy/authorization-for-expressjs)上的GitHub。

```
const { ExpressAuthorizationMiddleware } = require('@cedar-policy/authorization-for-expressjs');

const { AVPAuthorizationEngine } = require('@verifiedpermissions/authorization-clients');

const avpAuthorizationEngine = new AVPAuthorizationEngine({
    policyStoreId: 'policy-store-id',
    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) => console.log(s),
        log: (s) => console.log(s),
    }
});

// Add the middleware to your Express application
app.use(expressAuthorization.middleware);
```

## 测试集成
<a name="testing-authorization"></a>

您可以使用不同的用户令牌向 API 端点发出请求，从而测试您的授权实现。授权中间件将根据您定义的策略自动评估每个请求。

例如，如果您设置了具有不同权限的不同用户组：
+ 管理员：对所有资源和管理功能的完全访问权限
+ 员工：可以查看、创建和更新资源
+ 客户：只能查看资源

您可以通过使用不同的用户登录并尝试各种操作来验证权限策略是否按预期运行。在 Express 应用程序的终端中，您可以看到日志输出，其中提供了有关授权决策的更多详细信息。

## 问题排查
<a name="troubleshooting"></a>

如果授权失败，请尝试以下方法：  
+ 验证您的保单商店 ID 是否正确
+ 确保您的身份源配置正确
+ 检查您的政策格式是否正确
+ 验证您的 JWT 令牌是否有效

## 后续步骤
<a name="express-integration-next-steps"></a>

实现基本集成后，请考虑：
+ 为特定的授权场景实现自定义映射器
+ 为授权决策设置监控和日志记录
+ 为不同的用户角色创建其他策略