本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
自訂身分驗證挑戰 Lambda 觸發器
當您建置 Amazon Cognito 使用者集區的身分驗證流程時,您可能會發現想要將身分驗證模型延伸到內建流程之外。自訂挑戰觸發的一個常見使用案例是實作使用者名稱、密碼和多重要素驗證 (MFA) 以外的其他安全檢查。自訂挑戰是您可以使用 Lambda 支援的程式設計語言產生的任何問題和回應。例如,您可能想要要求使用者先解決 CAPTCHA 或回答安全問題,才能進行身分驗證。另一個潛在需求是整合特殊身分驗證因素或裝置。或者,您可能已經開發了使用硬體安全金鑰或生物識別裝置來驗證使用者身分的軟體。自訂挑戰的身分驗證成功定義是 Lambda 函數接受的正確答案:固定字串,例如外部 API 的滿意回應。
您可以使用自訂挑戰開始身分驗證,並完全控制身分驗證程序,或者您可以在應用程式收到自訂挑戰之前執行使用者名稱密碼身分驗證。
自訂身分驗證挑戰 Lambda 觸發條件:
這三個 Lambda 函數會鏈結在一起,以呈現完全在您的控制範圍內且屬於您自己的設計的身分驗證機制。由於自訂身分驗證需要用戶端和 Lambda 函數中的應用程式邏輯,因此您無法在受管登入中處理自訂身分驗證。此身分驗證系統需要額外的開發人員工作。您的應用程式必須使用使用者集區 API 執行身分驗證流程,並使用在自訂身分驗證挑戰中心轉譯問題的自訂建立登入介面來處理產生的挑戰。
如需實作自訂身分驗證的詳細資訊,請參閱 自訂身分驗證流程與挑戰
API 操作 InitiateAuth 或 AdminInitiateAuth 與 RespondToAuthChallenge 或 AdminRespondToAuthChallenge 之間的身分驗證。在此流程中,使用者身分驗證會透過回答連續挑戰,直到驗證失敗或者使用者發出字符為止。挑戰回應可能是新的挑戰。在這種情況下,您的應用程式會視需要回應新挑戰的次數。當定義身分驗證挑戰函數分析到目前為止的結果、判斷所有挑戰都已回答,並傳回 時,就會成功進行身分驗證IssueTokens。
自訂挑戰流程中的 SRP 身分驗證
您可以讓 Amazon Cognito 在發出自訂挑戰之前驗證使用者密碼。當您在自訂挑戰流程中執行 SRP 驗證時,會執行請求率配額驗證類別中關聯的任何 Lambda 觸發程序。下列為此程序的概觀:
-
您的應用程式使用
AuthParameters對應透過呼叫InitiateAuth或AdminInitiateAuth啟動登入。參數必須包含CHALLENGE_NAME: SRP_A,以及SRP_A和USERNAME的值。 -
Amazon Cognito 以包含
challengeName: SRP_A和challengeResult: true初始工作階段,叫用您的定義驗證挑戰 Lambda 觸發程序。 -
收到這些輸入後,您的 Lambda 函數會以
challengeName: PASSWORD_VERIFIER、issueTokens: false、failAuthentication: false回應。 -
如果密碼驗證成功,Amazon Cognito 會再次以包含
challengeName: PASSWORD_VERIFIER和challengeResult: true的新工作階段,叫用您的 Lambda 函數。 -
您的 Lambda 函數會以
challengeName: CUSTOM_CHALLENGE、issueTokens: false和failAuthentication: false回應,啟動您的自訂挑戰。如果您不想透過密碼驗證開始自訂驗證流程,您可以使用AuthParameters對應 (包括CHALLENGE_NAME: CUSTOM_CHALLENGE) 啟動登入。 -
除非已回答所有挑戰,否則挑戰迴圈會不斷重複。
以下是在具有 SRP 流程的自訂身分驗證之前啟動InitiateAuth請求的範例。
{ "AuthFlow": "CUSTOM_AUTH", "ClientId": "1example23456789", "AuthParameters": { "CHALLENGE_NAME": "SRP_A", "USERNAME": "testuser", "SRP_A": "[SRP_A]", "SECRET_HASH": "[secret hash]" } }
自訂身分驗證 SRP 流程中的密碼重設
當使用者處於 FORCE_CHANGE_PASSWORD 狀態時,您的自訂身分驗證流程必須整合密碼變更步驟,同時保持身分驗證挑戰的完整性。Amazon Cognito 會在挑戰期間調用您的定義身分驗證NEW_PASSWORD_REQUIRED挑戰 Lambda 觸發條件。在這種情況下,使用自訂挑戰流程和 SRP 身分驗證登入的使用者如果處於密碼重設狀態,則可以設定新密碼。
當使用者處於 RESET_REQUIRED或 FORCE_CHANGE_PASSWORD 狀態時,必須使用 回應NEW_PASSWORD_REQUIRED挑戰NEW_PASSWORD。在搭配 SRP 的自訂身分驗證中,Amazon Cognito 會在使用者完成 SRP NEW_PASSWORD_REQUIRED挑戰後傳回PASSWORD_VERIFIER挑戰。您的定義身分驗證挑戰觸發會在session陣列中接收兩個挑戰結果,並在使用者成功變更其密碼後繼續進行其他自訂挑戰。
您的定義驗證挑戰 Lambda 觸發程序必須透過 SRP 身分驗證、密碼重設和後續自訂挑戰來管理挑戰序列。觸發會在 session 參數中收到一系列已完成的挑戰,包括 PASSWORD_VERIFIER和 NEW_PASSWORD_REQUIRED結果。如需實作範例,請參閱 定義驗證挑戰範例。
身分驗證流程步驟
對於需要在自訂挑戰之前驗證其密碼的使用者,程序會遵循下列步驟:
-
您的應用程式使用
AuthParameters對應透過呼叫InitiateAuth或AdminInitiateAuth啟動登入。參數必須包含CHALLENGE_NAME: SRP_A、 和SRP_A和 的值USERNAME。 -
Amazon Cognito 以包含
challengeName: SRP_A和challengeResult: true初始工作階段,叫用您的定義驗證挑戰 Lambda 觸發程序。 -
收到這些輸入後,您的 Lambda 函數會以
challengeName: PASSWORD_VERIFIER、issueTokens: false、failAuthentication: false回應。 -
如果密碼驗證成功,會發生下列兩種情況之一:
- 對於處於正常狀態的使用者:
-
Amazon Cognito 會使用包含
challengeName: PASSWORD_VERIFIER和 的新工作階段再次調用 Lambda 函數challengeResult: true。您的 Lambda 函數會以
challengeName: CUSTOM_CHALLENGE、issueTokens: false和failAuthentication: false回應,啟動您的自訂挑戰。 - 對於處於
RESET_REQUIRED或FORCE_CHANGE_PASSWORD狀態的使用者: -
Amazon Cognito 會使用包含
challengeName: PASSWORD_VERIFIER和 的工作階段來叫用 Lambda 函數challengeResult: true。您的 Lambda 函數應以
challengeName: NEW_PASSWORD_REQUIRED、issueTokens: false和failAuthentication: false回應。成功變更密碼後,Amazon Cognito 會使用包含
PASSWORD_VERIFIER和NEW_PASSWORD_REQUIRED結果的工作階段來叫用 Lambda 函數。您的 Lambda 函數會以
challengeName: CUSTOM_CHALLENGE、issueTokens: false和failAuthentication: false回應,啟動您的自訂挑戰。
-
除非已回答所有挑戰,否則挑戰迴圈會不斷重複。
如果您不想透過密碼驗證開始自訂驗證流程,您可以使用 AuthParameters 對應 (包括 CHALLENGE_NAME: CUSTOM_CHALLENGE) 啟動登入。
工作階段管理
身分驗證流程會透過一系列工作階段 IDs和挑戰結果來維持工作階段連續性。每個挑戰回應都會產生新的工作階段 ID,以防止工作階段重複使用錯誤,這對多重驗證流程特別重要。
挑戰結果會依時間順序儲存在 Lambda 觸發程序接收的工作階段陣列中。對於處於 FORCE_CHANGE_PASSWORD 狀態的使用者,工作階段陣列包含:
session[0]- 初始SRP_A挑戰session[1]-PASSWORD_VERIFIER結果session[2]-NEW_PASSWORD_REQUIRED結果後續元素 - 其他自訂挑戰的結果
驗證流程範例
下列範例示範FORCE_CHANGE_PASSWORD狀態為 必須同時完成密碼變更和自訂 CAPTCHA 挑戰之使用者的完整自訂身分驗證流程。
-
InitiateAuth 請求
{ "AuthFlow": "CUSTOM_AUTH", "ClientId": "1example23456789", "AuthParameters": { "CHALLENGE_NAME": "SRP_A", "USERNAME": "testuser", "SRP_A": "[SRP_A]" } } -
InitiateAuth 回應
{ "ChallengeName": "PASSWORD_VERIFIER", "ChallengeParameters": { "USER_ID_FOR_SRP": "testuser" }, "Session": "[session_id_1]" } -
使用 的 RespondToAuthChallenge 請求
PASSWORD_VERIFIER{ "ChallengeName": "PASSWORD_VERIFIER", "ClientId": "1example23456789", "ChallengeResponses": { "PASSWORD_CLAIM_SIGNATURE": "[claim_signature]", "PASSWORD_CLAIM_SECRET_BLOCK": "[secret_block]", "TIMESTAMP": "[timestamp]", "USERNAME": "testuser" }, "Session": "[session_id_1]" } -
RespondToAuthChallenge 回應與
NEW_PASSWORD_REQUIRED挑戰{ "ChallengeName": "NEW_PASSWORD_REQUIRED", "ChallengeParameters": {}, "Session": "[session_id_2]" } -
使用 的 RespondToAuthChallenge 請求
NEW_PASSWORD_REQUIRED{ "ChallengeName": "NEW_PASSWORD_REQUIRED", "ClientId": "1example23456789", "ChallengeResponses": { "NEW_PASSWORD": "[password]", "USERNAME": "testuser" }, "Session": "[session_id_2]" } -
使用 CAPTCHA 自訂挑戰的 RespondToAuthChallenge 回應
{ "ChallengeName": "CUSTOM_CHALLENGE", "ChallengeParameters": { "captchaUrl": "url/123.jpg" }, "Session": "[session_id_3]" } -
RespondToAuthChallenge 請求與 CAPTCHA 自訂挑戰的答案
{ "ChallengeName": "CUSTOM_CHALLENGE", "ClientId": "1example23456789", "ChallengeResponses": { "ANSWER": "123", "USERNAME": "testuser" }, "Session": "[session_id_3]" }
6. 最終成功回應
{ "AuthenticationResult": { "AccessToken": "eyJra456defEXAMPLE", "ExpiresIn": 3600, "IdToken": "eyJra789ghiEXAMPLE", "RefreshToken": "eyJjd123abcEXAMPLE", "TokenType": "Bearer" }, "ChallengeParameters": {} }