整合 REST API 與 Amazon Cognito 使用者集區 - Amazon API Gateway

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

整合 REST API 與 Amazon Cognito 使用者集區

建立 Amazon Cognito 使用者集區後,您必須在 API Gateway 中建立使用該使用者集區的 COGNITO_USER_POOLS 授權方。下列程序示範如何使用 API Gateway 主控台來執行此操作。

注意

您可以使用 CreateAuthorizer 動作來建立使用多個使用者集區的 COGNITO_USER_POOLS 授權者。一個 COGNITO_USER_POOLS 授權者最多可以使用 1,000 個使用者集區。此限制無法提高。

重要

執行下列任何程序之後,您需要部署或重新部署您的 API 以傳播變更。如需部署 API 的詳細資訊,請參閱 在 API Gateway 中部署其餘 API

使用 API Gateway 主控台建立 COGNITO_USER_POOLS 授權方
  1. 在 API Gateway 中建立新的 API 或選取現有的 API。

  2. 在主導覽窗格中,選擇授權方

  3. 選擇建立授權方

  4. 若要設定新的授權方使用使用者集區,請執行下列操作:

    1. 針對授權方名稱,輸入名稱。

    2. 針對授權方類型,選取 Cognito

    3. 對於 Cognito 使用者集區,請選擇您建立 Amazon Cognito 的 AWS 區域 位置,然後選取可用的使用者集區。

      您可以使用階段變數來定義使用者集區。使用下列格式適用於您的使用者集區:arn:aws:cognito-idp:us-east-2:111122223333:userpool/${stageVariables.MyUserPool}

    4. 針對權杖來源,輸入 Authorization 作為標頭名稱,以在使用者成功登入時,傳遞 Amazon Cognito 傳回的身分或存取權杖。

    5. (選用) 在權杖驗證欄位中輸入規則表達式,以驗證身分權杖的 aud (對象) 欄位,再透過 Amazon Cognito 授權請求。請注意,當使用存取字符時,由於存取字符不包含該 aud 字段,所以此驗證拒絕該請求。

    6. 選擇建立授權方

  5. 建立 COGNITO_USER_POOLS 授權方之後,您可以提供從使用者集區佈建的身分字符,選擇性地對它進行呼叫測試。您可以呼叫 Amazon Cognito 身分軟體開發套件來取得此身分字符,藉此執行使用者登入。您也可以使用 InitiateAuth​ 動作。如果您未設定任何授權範圍,API Gateway 會將提供的權杖視為身分權杖。

上述程序會建立使用新建立之 Amazon Cognito 使用者集區的 COGNITO_USER_POOLS 授權方。視您在 API 方法中啟用授權方的方式而定,您可以使用從已整合使用者集區佈建的身分字符或存取字符。

在方法中設定 COGNITO_USER_POOLS 授權方
  1. 選擇資源。選擇新方法或選擇現有方法。如有需要,請建立資源。

  2. 方法請求索引標籤的方法請求設定下,選擇編輯

  3. 針對授權方,從下拉式選單選取您剛才建立的 Amazon Cognito 使用者集區授權方

  4. 若要使用身分字符,請執行下列操作:

    1. 授權範圍保留空白。

    2. 如有需要,在整合請求中,於內文對應範本中新增 $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']" } }
  5. 若要使用存取字符,請執行下列操作:

    1. 針對授權範圍,輸入在建立 Amazon Cognito 使用者集區時所設定之範圍的一或多個完整名稱。例如,在 為 REST API 建立 Amazon Cognito 使用者集區 提供的範例之後,其中一個範圍是 https://my-petstore-api.example.com/cats.read

      在執行時間,如果在這個步驟中,方法內指定的任何範圍符合傳入字符宣告的範圍,則方法呼叫就會成功。否則,呼叫失敗並傳回 401 Unauthorized 回應。

    2. 選擇儲存

  6. 為您選擇的其他方法重複這些步驟。

使用 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. 指定 COGNITO_USER_POOLS 授權方 (MyUserPool) JSON 定義,做為 OpenAPI 3.0 的 securitySchemes 部分或 Open API 2.0 的 securityDefinitions 部分,如下所示:

    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": ["https://my-petstore-api.example.com/cats.read", "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 組態設定。如需詳細資訊,請參閱 適用於 API Gateway 的 OpenAPI 擴充功能