Amazon API Gateway
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

将 REST API 与 Amazon Cognito 用户池集成

在 API Gateway 中创建 Amazon Cognito 用户池之后,接下来您必须创建使用用户池的 COGNITO_USER_POOLS 授权方。使用 API Gateway 控制台进行这一操作的具体步骤如下。

重要

在执行以下任意步骤之后,您都需要部署或重新部署 API 以便传播更改。有关部署 API 的更多信息,请参阅在 Amazon API Gateway 中部署 REST API

使用 API Gateway 控制台创建 COGNITO_USER_POOLS 授权方

  1. 在 API Gateway 中创建一个新 API 或选择现有 API。

  2. 从主导航窗格中,选择指定 API 下的 Authorizers (授权方)

  3. Authorizers (授权方) 下,选择 Create New Authorizer (新建授权方)

  4. 要配置新的授权方来使用用户池,请执行以下操作:

    1. Name (名称) 中键入授权方名称。

    2. 选择 Cognito 选项。

    3. Cognito User Pool (Cognito 用户池) 下选择一个区域。

    4. 选择一个可用的用户池。您必须已为 Amazon Cognito 中的所选区域创建了用户池才能使它显示在下拉列表中。

    5. 对于 Token source (令牌源),键入 Authorization 作为标头名称,以在用户成功登录时传递 Amazon Cognito 所返回的身份令牌或访问令牌。

    6. (可选)在 Token validation (令牌验证) 字段中键入一个正则表达式,在使用 Amazon Cognito 对请求进行授权之前验证身份令牌的 aud 字段。

    7. 要完成用户池与 API 的集成,请选择 Create (创建)

  5. 创建了 COGNITO_USER_POOLS 授权方之后,您可以通过提供从用户池预置的身份验证令牌来对其进行测试调用。您可以通过调用 Amazon Cognito 身份开发工具包 来获取此身份令牌以执行用户登录。确保使用的是返回的身份令牌,而不是访问令牌。

上述过程创建使用新 Amazon Cognito 用户池的 COGNITO_USER_POOLS 授权方。根据在 API 方法上启用授权方的方法,您可以使用从集成用户池预置的身份令牌或访问令牌。下一过程将引导您完成在 API 方法上配置授权方的步骤。

在方法上配置 COGNITO_USER_POOLS 授权方

  1. 选择(或创建)API 的一个方法。

  2. 选择 Method Request (方法请求)

  3. Settings (设置) 下,选择 Authorization (授权) 旁边的铅笔图标。

  4. 从下拉列表中选择可用的 Amazon Cognito 用户池授权方之一。

  5. 要保存设置,请选择对勾图标。

  6. 要使用身份令牌,请执行以下操作:

    1. 保留 OAuth Scopes (OAuth 范围) 选项为不指定(为 NONE)。

    2. 如果需要,请选择 Integration Request (集成请求) 以在正文映射模板中添加 $context.authorizer.claims['property-name']$context.authorizer.claims.property-name 表达式,从而将指定的身份声明属性从用户池传递到后端。对于简单的属性名称,例如 subcustom-sub,两种表示法相同。对于复杂的属性名称,例如 custom:role,不能使用点表示法。例如,以下映射表达式会将声明的 subemail标准字段传递到后端:

      { "context" : { "sub" : "$context.authorizer.claims.sub", "email" : "$context.authorizer.claims.email" } }

      如果您在配置用户池时声明了自定义声明字段,那么您可以用同样的方式来访问自定义字段。以下示例获取的是声明的自定义 role 字段:

      { "context" : { "role" : "$context.authorizer.claims.role" } }

      如果自定义声明字段被声明为 custom:role,可以使用以下示例来获取声明的属性:

      { "context" : { "role" : "$context.authorizer.claims['custom:role']" } }
  7. 要使用访问令牌,请执行以下操作:

    1. 选择 OAuth Scopes (OAuth 范围) 旁的铅笔图标。

    2. 键入某个范围的一个或多个全名,该范围在创建 Amazon Cognito 用户池时已配置。例如,根据 为 REST API 创建 Amazon Cognito 用户池 中给出的示例,其中一个范围是 com.hamuta.movies/drama.view。使用单个空格分隔多个范围。

      在运行时,如果在此步骤的方法上指定的任何范围与在传入令牌中声明的范围匹配,则方法调用成功。否则,调用失败并出现 401 Unauthorized 响应。

    3. 要保存设置,请选择对勾图标。

  8. 对您选择的其他方法重复这些步骤。

使用 COGNITO_USER_POOLS 授权方,如果未指定 OAuth Scopes (OAuth 范围) 选项,则 API Gateway 将提供的令牌视为身份令牌,并根据来自用户池的身份之一验证所声明的身份。否则,API Gateway 将提供的令牌视为访问令牌,并根据在方法上声明的授权范围,验证在令牌中所声明的访问范围。

除了使用 API Gateway 控制台之外,您还可以指定 OpenAPI 定义文件并将 API 定义导入到 API Gateway,从而在方法上启用 Amazon Cognito 用户池。

用 OpenAPI 定义文件导入 COGNITO_USER_POOLS 授权方

  1. 为您的 API 创建(或导出)一个 OpenAPI 定义文件。

  2. 作为 OpenAPI 3.0 中的 securitySchemes 部分或 Open API 2.0 中的 securityDefinitions 部分,指定 COGNITO_USER_POOLS 授权方 (MyUserPool) JSON 定义,如下所示:

    OpenAPI 3.0OpenAPI 2.0
    OpenAPI 3.0
    "securitySchemes": { "MyUserPool": { "type": "apiKey", "name": "Authorization", "in": "header", "x-amazon-apigateway-authtype": "cognito_user_pools", "x-amazon-apigateway-authorizer": { "type": "cognito_user_pools", "providerARNs": [ "arn:aws:cognito-idp:{region}:{account_id}:userpool/{user_pool_id}" ] } }
    OpenAPI 2.0
    "securityDefinitions": { "MyUserPool": { "type": "apiKey", "name": "Authorization", "in": "header", "x-amazon-apigateway-authtype": "cognito_user_pools", "x-amazon-apigateway-authorizer": { "type": "cognito_user_pools", "providerARNs": [ "arn:aws:cognito-idp:{region}:{account_id}:userpool/{user_pool_id}" ] } }
  3. 要将身份令牌用于方法授权,请将 { "MyUserPool": [] } 添加到方法的 security 定义,如根资源上的以下 GET 方法所示。

    "paths": { "/": { "get": { "consumes": [ "application/json" ], "produces": [ "text/html" ], "responses": { "200": { "description": "200 response", "headers": { "Content-Type": { "type": "string" } } } }, "security": [ { "MyUserPool": [] } ], "x-amazon-apigateway-integration": { "type": "mock", "responses": { "default": { "statusCode": "200", "responseParameters": { "method.response.header.Content-Type": "'text/html'" }, } }, "requestTemplates": { "application/json": "{\"statusCode\": 200}" }, "passthroughBehavior": "when_no_match" } }, ... }
  4. 要为方法授权使用访问令牌,请将以上安全定义更改为 { "MyUserPool": [resource-server/scope, ...] }

    "paths": { "/": { "get": { "consumes": [ "application/json" ], "produces": [ "text/html" ], "responses": { "200": { "description": "200 response", "headers": { "Content-Type": { "type": "string" } } } }, "security": [ { "MyUserPool": ["com.hamuta.movies/drama.view", "http://my.resource.com/file.read"] } ], "x-amazon-apigateway-integration": { "type": "mock", "responses": { "default": { "statusCode": "200", "responseParameters": { "method.response.header.Content-Type": "'text/html'" }, } }, "requestTemplates": { "application/json": "{\"statusCode\": 200}" }, "passthroughBehavior": "when_no_match" } }, ... }
  5. 如果需要,您可以使用合适的 OpenAPI 定义或扩展来设置其他 API 配置设置。有关更多信息,请参阅 基于 OpenAPI 的 API Gateway 扩展