返回文章列表

Cognito應用程式安全驗證與整合

本文探討 Amazon Cognito 的應用程式安全驗證機制,涵蓋客戶端驗證流程、使用者自行註冊與管理員確認註冊,以及使用者群組管理。文章提供 AWS CLI 命令和程式碼範例,詳細說明每個步驟,並以圖表輔助理解。此外,文章也介紹如何將 Cognito 與 API Gateway

Web 開發 資安

Amazon Cognito 提供強大的身分驗證與授權服務,簡化應用程式安全管理。本文著重於 Cognito 的客戶端驗證流程,使用 USER_PASSWORD_AUTH 流程,並逐步示範如何建立使用者池客戶端、執行驗證流程、使用重新整理令牌等關鍵步驟。同時,文章也涵蓋使用者自行註冊、管理員確認註冊兩種流程,並提供 AWS CLI 命令和 Python 程式碼範例。此外,文章也說明如何管理 Cognito 使用者群組,以及如何將 Cognito 與 API Gateway 整合,以確保 API 的安全性,並提供 Postman 測試方法。這些技術有助於開發者建構安全可靠的 Web 應用程式,並有效管理使用者許可權。

使用 Amazon Cognito 進行應用程式安全驗證 - 第四章:客戶端驗證流程實作

在前面的章節中,我們探討了伺服器端驗證流程,並使用了 ADMIN_NO_SRP_AUTH 驗證流程型別。在本章節中,我們將著重介紹客戶端驗證流程,並使用 USER_PASSWORD_AUTH 驗證流程型別。

準備工作

在開始之前,請確保您已經按照「建立 Cognito 使用者池」章節的步驟,成功建立了一個 Cognito 使用者池。

客戶端驗證流程實作步驟

1. 建立 Cognito 使用者池客戶端

首先,我們需要建立一個使用者池客戶端,以便進行客戶端驗證流程。我們將使用 AWS CLI 和 CloudFormation 範本兩種方式來完成此步驟。

使用 AWS CLI 建立使用者池客戶端

執行以下命令:

aws cognito-idp create-user-pool-client \
--user-pool-id us-east-1_fYsb1Gyec \
--client-name my-user-pool-client \
--explicit-auth-flows USER_PASSWORD_AUTH \
--profile admin

在這裡,我們指定了 USER_PASSWORD_AUTH 作為明確的驗證流程。需要注意的是,ADMIN_NO_SRP_AUTH 只支援伺服器端驗證流程,而 USER_PASSWORD_AUTH 則支援使用者從舊應用程式遷移。

使用 CloudFormation 範本建立使用者池客戶端

對應的 CloudFormation 範本如下:

Resources:
  MyUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      ClientName: 'My Cognito User Pool Client'
      ExplicitAuthFlows:
        - USER_PASSWORD_AUTH
      RefreshTokenValidity: 30
      UserPoolId: !ImportValue MyFirstUserPoolId

Outputs:
  ClientId:
    Description: 'Cognito user pool Client'
    Value: !Ref MyUserPoolClient

2. 執行客戶端驗證流程

接下來,我們將按照以下步驟來演示客戶端驗證流程:

  1. 建立使用者:使用管理員 API 建立一個新使用者。

aws cognito-idp admin-create-user
–user-pool-id us-east-1_fYsb1Gyec
–username testuser2
–temporary-password Passw0rd$
–profile admin

   使用者的預設狀態將是 `FORCE_CHANGE_PASSWORD`。

2. **啟動驗證流程**:
   ```bash
aws cognito-idp initiate-auth \
--client-id 3jiv1fi1rspotsst9m19hktu58 \
--auth-flow USER_PASSWORD_AUTH \
--auth-parameters USERNAME=testuser2,PASSWORD=Passw0rd$

由於這是非管理員 API,因此不需要指定 --profile admin。該命令將傳回一個 NEW_PASSWORD_REQUIRED 質詢和一個會話 ID。

  1. 回應驗證質詢

aws cognito-idp respond-to-auth-challenge
–client-id 3jiv1fi1rspotsst9m19hktu58
–challenge-name NEW_PASSWORD_REQUIRED
–challenge-responses USERNAME=testuser2,NEW_PASSWORD=NewPass0123$
–session

   如果成功,該命令將傳回包含三個令牌的回應:存取令牌、重新整理令牌和 ID 令牌。

4. **使用重新整理令牌重新生成存取令牌和 ID 令牌**:
   ```bash
aws cognito-idp initiate-auth \
--client-id 3jiv1fi1rspotsst9m19hktu58 \
--auth-flow REFRESH_TOKEN_AUTH \
--auth-parameters REFRESH_TOKEN=<refresh token>
  1. 清理
    • 刪除使用者池客戶端:

aws cognito-idp delete-user-pool-client
–user-pool-id us-east-1_fYsb1Gyec
–client-id 3jiv1fi1rspotsst9m19hktu58
–profile admin

   - 刪除為本章節建立的使用者:
     ```bash
aws cognito-idp admin-delete-user \
--user-pool-id us-east-1_fYsb1Gyec \
--username testuser2 \
--profile admin
程式碼解析:

以下是一個範例程式碼,用於演示客戶端驗證流程中的某個步驟,例如啟動驗證流程:

import boto3

cognito_idp = boto3.client('cognito-idp')

response = cognito_idp.initiate_auth(
    ClientId='3jiv1fi1rspotsst9m19hktu58',
    AuthFlow='USER_PASSWORD_AUTH',
    AuthParameters={
        'USERNAME': 'testuser2',
        'PASSWORD': 'Passw0rd$'
    }
)

print(response)

程式碼解密:

  • 該 Python 程式碼使用 boto3 函式庫與 AWS Cognito Identity Provider (Cognito IDP) 服務進行互動。
  • cognito_idp.initiate_auth 方法用於啟動使用者的驗證流程。
  • ClientId 指定了 Cognito 使用者池客戶端的 ID。
  • AuthFlow 設定為 USER_PASSWORD_AUTH,表示使用使用者名稱和密碼進行驗證。
  • AuthParameters 中包含了使用者名稱 (USERNAME) 和密碼 (PASSWORD)。
  • 程式碼輸出了 Cognito IDP 的回應,通常包含驗證結果或質詢。

圖表說明

@startuml
skinparam backgroundColor #FEFEFE
skinparam sequenceArrowThickness 2

title Cognito應用程式安全驗證與整合

actor "客戶端" as client
participant "API Gateway" as gateway
participant "認證服務" as auth
participant "業務服務" as service
database "資料庫" as db
queue "訊息佇列" as mq

client -> gateway : HTTP 請求
gateway -> auth : 驗證 Token
auth --> gateway : 認證結果

alt 認證成功
    gateway -> service : 轉發請求
    service -> db : 查詢/更新資料
    db --> service : 回傳結果
    service -> mq : 發送事件
    service --> gateway : 回應資料
    gateway --> client : HTTP 200 OK
else 認證失敗
    gateway --> client : HTTP 401 Unauthorized
end

@enduml

此圖示展示了客戶端驗證流程的主要步驟,包括啟動驗證流程、回應 Cognito 的質詢,以及使用重新整理令牌重新生成令牌。

使用 Amazon Cognito 進行應用程式安全:第 4 章 - 使用者註冊流程

概述

在前面的章節中,我們以管理員身份建立使用者。然而,在許多現實世界的應用程式中,包括大多數 Web 應用程式,都允許使用者自行註冊。本章節將示範如何使用 CLI 命令實作使用者自行註冊的流程,以及如何透過管理員確認使用者註冊。

準備工作

在開始之前,請確保您已經完成了以下準備工作:

  1. 依照「建立 Cognito 使用者池」章節的步驟,建立了一個 Cognito 使用者池。
  2. 依照「客戶端驗證」章節的步驟,建立了一個具有 USER_PASSWORD_AUTH 明確流程宣告的 Cognito 應用客戶端。

使用者註冊流程

本章節將介紹兩種註冊流程:使用者自行確認註冊和由管理員確認註冊。

使用者自行確認註冊

以下步驟描述瞭如何設定使用者自行確認註冊:

  1. 發起註冊流程:使用 sign-up 子命令,並提供使用者名稱和密碼。

    aws cognito-idp sign-up \
    --client-id 4s69op0v8es2cojl5ncjql2v4g \
    --username testuser4 \
    --password Passw0rd$ \
    --user-attributes Name=email,Value=[email protected]
    

    請將 [email protected] 替換為您的電子郵件地址。

  2. 確認註冊:收到確認碼後,使用 confirm-sign-up 子命令確認註冊。

    aws cognito-idp confirm-sign-up \
    --client-id 4s69op0v8es2cojl5ncjql2v4g \
    --username testuser4 \
    --confirmation-code 156202
    
  3. 登入驗證:使用 initiate-auth 子命令嘗試登入。

    aws cognito-idp initiate-auth \
    --client-id 4s69op0v8es2cojl5ncjql2v4g \
    --auth-flow USER_PASSWORD_AUTH \
    --auth-parameters USERNAME=testuser4,PASSWORD=Passw0rd$
    

    如果成功,您將收到包含 AccessTokenRefreshTokenIdToken 的回應。

  4. 刪除使用者:使用 delete-user 子命令刪除使用者。

    aws cognito-idp delete-user \
    --access-token <access token>
    

    請將 <access token> 替換為您在上一步收到的 AccessToken

使用者註冊由管理員確認

以下步驟描述瞭如何設定使用者註冊由管理員確認:

  1. 發起註冊流程:使用 sign-up 子命令,並提供使用者名稱和密碼。電子郵件是可選的。

    aws cognito-idp sign-up \
    --client-id 4s69op0v8es2cojl5ncjql2v4g \
    --username testuser4 \
    --password Passw0rd$
    
  2. 管理員確認使用者:使用 admin-confirm-sign-up 子命令確認使用者。

    aws cognito-idp admin-confirm-sign-up \
    --user-pool-id us-east-1_fYsb1Gyec \
    --username testuser4 \
    --profile admin
    
  3. 登入驗證:使用 initiate-auth 子命令嘗試登入,與自行確認註冊的步驟相同。

重點解析

  • 在現實世界的應用程式中,通常會根據使用的 SDK 平台選擇客戶端驗證或伺服器端驗證流程。
  • Amazon Cognito 支援多種驗證流程,包括自定義驗證流程和使用者遷移驗證流程。
  • 使用者註冊流程可以根據需求選擇自行確認或由管理員確認。

程式碼解析

aws cognito-idp sign-up \
--client-id 4s69op0v8es2cojl5ncjql2v4g \
--username testuser4 \
--password Passw0rd$ \
--user-attributes Name=email,Value=[email protected]

內容解密:

  1. aws cognito-idp sign-up:此命令用於發起使用者註冊流程。
  2. --client-id:指定 Cognito 應用客戶端的 ID。
  3. --username--password:指定使用者的名稱和密碼。
  4. --user-attributes:指定使用者的屬性,在此範例中為電子郵件地址。

使用 Amazon Cognito 進行應用程式安全 Chapter 4

使用者群組管理

Amazon Cognito 允許將使用者新增至不同的群組,並根據所屬群組對使用者進行不同的處理。例如,管理員使用者可以顯示管理員選單,而一般使用者則顯示一般選單。在本章節中,我們將探討如何建立和使用 Cognito 使用者池中的群組。

準備工作

  1. 依照「建立 Cognito 使用者池」章節的步驟,建立一個 Cognito 使用者池。

操作步驟

  1. 建立使用者:建立兩個使用者,分別命名為 admin_userregular_user
  2. 建立群組:使用以下命令建立一個名為 administrators 的群組:

aws cognito-idp create-group
–group-name ‘administrators’
–user-pool-id us-east-1_fYsb1Gyec
–description ‘Administrator Group’
–profile admin

   如果成功,將傳回以下回應:
   
3. **建立另一個群組**:使用相同的命令建立一個名為 `authenticated_users` 的群組。
4. **將使用者新增至群組**:使用以下命令將 `regular_user` 新增至 `authenticated_users` 群組:
   ```bash
aws cognito-idp admin-add-user-to-group \
--user-pool-id us-east-1_fYsb1Gyec \
--username regular_user \
--group-name authenticated_users \
--profile admin
  1. 將管理員使用者新增至多個群組:使用相同的命令將 admin_user 新增至 administratorsauthenticated_users 群組。
  2. 檢查使用者所屬群組:使用以下命令檢查 admin_user 所屬的群組:

aws cognito-idp admin-list-groups-for-user
–username admin_user
–user-pool-id us-east-1_fYsb1Gyec
–profile admin

   如果成功,將傳回 `admin_user` 所屬的兩個群組的詳細資訊。

#### 操作原理

本章節示範瞭如何將使用者新增至群組,以及如何檢查使用者所屬的群組。一旦知道使用者所屬的群組,就可以根據所屬群組對使用者進行不同的處理。

#### 更多資訊

我們還可以將 IAM 角色與群組關聯,允許使用者根據所屬角色及其相關政策存取不同的 AWS 服務。要附加角色,可以使用 `aws cognito-idp admin-list-groups-for-user` 命令的 `role-arn` 屬性。

### 將 Cognito 與 API Gateway 整合

在本章節中,我們將把 Cognito Authorizer 與 API Gateway 整合,並使用 Postman REST 客戶端進行測試。

#### 準備工作

1. 依照「建立 Cognito 使用者池」章節的步驟,建立一個 Cognito 使用者池。
2. 依照「客戶端驗證」章節的步驟,建立一個具有 `USER_PASSWORD_AUTH` 明確流程宣告的 Cognito 應用程式客戶端。

#### 操作步驟

1. **建立 API Gateway REST API**:
   ```bash
aws apigateway create-rest-api \
--name "API Gateway With Cognito" \
--region us-east-1 \
--profile admin
  1. 取得根資源 ID

aws apigateway get-resources
–rest-api-id 3t0t98ifdh
–region us-east-1
–profile admin

3. **建立資源**:
   ```bash
aws apigateway create-resource \
--rest-api-id 3t0t98ifdh \
--region us-east-1 \
--parent-id ufgvoiu8yh \
--path-part greeting \
--profile admin
  1. 建立 Cognito Authorizer

aws apigateway create-authorizer
–rest-api-id 3t0t98ifdh
–name First_Cognito_Custom_Authorizer
–type COGNITO_USER_POOLS
–provider-arns arn:aws:cognito-idp:us-east-1::userpool/us-east-1_fYsb1Gyec
–identity-source method.request.header.Authorization
–profile admin

   請將 `<account id>` 和 `us-east-1_fYsb1Gyec` 替換為您的實際帳戶 ID 和使用者池 ID。

#### 操作原理

本章節示範瞭如何將 Cognito Authorizer 與 API Gateway 整合。這是建置端對端無伺服器網頁應用程式的重要一步。

#### 更多資訊

更多關於 Cognito 和 API Gateway 的整合,請參閱 AWS 檔案和其他相關資源。