

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

# Amazon Cognito 使用者集區的安全最佳實務
<a name="user-pool-security-best-practices"></a>

當您想要防範常見威脅時，此頁面說明您可以實作的安全最佳實務。您選擇的組態將取決於每個應用程式的使用案例。我們建議您至少將最低權限套用至管理操作，並採取動作來保護應用程式和使用者秘密。您可以採取的另一個進階但有效的步驟是設定 AWS WAF Web ACLs 並將其套用至您的使用者集區。

## 在網路層級保護您的使用者集區
<a name="user-pool-security-best-practices-network"></a>

AWS WAF Web ACLs 可以保護您使用 Amazon Cognito 建置的身分驗證機制的效能和成本。透過 Web ACLs，您可以在 API 和受管登入請求前實作護欄。Web ACLs會建立網路和應用程式層篩選條件，以根據您設計的規則捨棄流量或需要 CAPTCHA。在請求符合 Web ACL 規則中的資格之前，不會將請求傳遞到您的 Amazon Cognito 資源。如需詳細資訊，請參閱 [AWS WAF Web ACLs](user-pool-waf.md)。

## 防止簡訊濫用
<a name="user-pool-security-best-practices-sms"></a>

當您允許在使用者集區中公開註冊時，您可以使用 Amazon Cognito 在簡訊中傳送的代碼來設定帳戶驗證。SMS 訊息可以與不需要的活動相關聯，並增加您的 AWS 帳單。設定您的基礎設施，以在發生詐騙時彈性地傳送簡訊。如需詳細資訊，請參閱部落格 AWS 中的下列文章。
+ [使用 Amazon Cognito 使用者集區降低使用者註冊詐騙和 SMS 幫浦的風險](https://aws.amazon.com/blogs/security/reduce-risks-of-user-sign-up-fraud-and-sms-pumping-with-amazon-cognito-user-pools/)
+ [防禦 SMS Pumping：協助對抗人工膨脹流量的新 AWS 功能](https://aws.amazon.com/blogs/messaging-and-targeting/defending-against-sms-pumping-new-aws-features-to-help-combat-artificially-inflated-traffic/)

## 了解公有身分驗證
<a name="user-pool-security-best-practices-public-operations"></a>

Amazon Cognito 使用者集區具有客戶身分和存取管理 (CIAM) 功能，支援一般大眾可以註冊使用者帳戶和存取應用程式的使用案例。當使用者集區允許自助註冊時，可以從公有網際網路請求使用者帳戶。自助式請求來自 [SignUp](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SignUp.html) 和 [InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) 等 API 操作，以及來自使用者與受管登入的互動。您可以設定使用者集區，以減輕可能來自公有請求的濫用，或完全停用公有身分驗證操作。

下列設定是您可以在使用者集區和應用程式用戶端中管理公有和內部身分驗證請求的一些方式。


**影響公有使用者集區存取的使用者集區設定範例**  

| 設定 | 可用選項 | 在 上設定 | 對公有身分驗證的影響 | 主控台設定 | API 操作和參數 | 
| --- | --- | --- | --- | --- | --- | 
| [自助式註冊](user-pool-settings-admin-create-user-policy.md) | 允許使用者註冊帳戶或以管理員身分建立使用者帳戶。 | 使用者集區 | 防止公開註冊 | 註冊 – 自助式註冊 | [CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html#CognitoUserPools-CreateUserPool-request-AdminCreateUserConfig)、[UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html#CognitoUserPools-UpdateUserPool-request-AdminCreateUserConfig)<br />`AdminCreateUserConfig` – `AllowAdminCreateUserOnly` | 
| [管理員確認](signing-up-users-in-your-app.md#signing-up-users-in-your-app-and-confirming-them-as-admin) | 傳送確認碼給新使用者，或要求管理員確認。 | 使用者集區 | 防止在沒有管理員動作的情況下確認註冊 | 註冊 – Cognito 協助的驗證和確認 | [CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html#CognitoUserPools-CreateUserPool-request-AccountRecoverySetting)、[UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html#CognitoUserPools-UpdateUserPool-request-AccountRecoverySetting)<br />`AccountRecoverySettings` – `admin_only` | 
| [使用者公開](cognito-user-pool-managing-errors.md) | 在登入和密碼重設或防止公開時傳遞「找不到使用者」訊息。 | 應用程式用戶端 | 防止猜測登入名稱、電子郵件地址或電話號碼 | 應用程式用戶端 – 防止使用者存在錯誤 | [CreateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html#CognitoUserPools-CreateUserPoolClient-request-PreventUserExistenceErrors)、[UpdateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPoolClient.html#CognitoUserPools-UpdateUserPoolClient-request-PreventUserExistenceErrors)<br />`PreventUserExistenceErrors` | 
| [Client secret](user-pool-settings-client-apps.md#user-pool-settings-client-app-client-types) (用戶端密碼) | 在註冊、登入、密碼重設時需要或不需要秘密雜湊 | 應用程式用戶端 | 防止來自未經授權來源的身分驗證請求 | 應用程式用戶端 – 用戶端秘密 | [CreateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html#CognitoUserPools-CreateUserPoolClient-request-GenerateSecret)<br />`GenerateSecret` | 
| [Web ACLs](user-pool-waf.md) | 啟用或停用身分驗證請求的網路防火牆 | 使用者集區 | 根據管理員定義的請求特性和 IP 地址規則來限制或防止存取 | AWS WAF – WAF 設定 | [AssociateWebACL](https://docs.aws.amazon.com/waf/latest/APIReference/API_AssociateWebACL.html#WAF-AssociateWebACL-request-ResourceArn)<br />`ResourceArn` | 
| [外部 IdP](cognito-user-pools-identity-provider.md) | 允許第三方 IdPs、使用者集區目錄或兩者中的使用者登入 | 應用程式用戶端 | 從註冊和登入中排除[本機使用者](cognito-terms.md#terms-localuser)或[聯合身分使用者](cognito-terms.md#terms-federateduser)。 | 應用程式用戶端 – 身分提供者 | [CreateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html#CognitoUserPools-CreateUserPoolClient-request-SupportedIdentityProviders)、[UpdateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPoolClient.html#CognitoUserPools-UpdateUserPoolClient-request-SupportedIdentityProviders)<br />`SupportedIdentityProviders` | 
| [授權伺服器](cognito-user-pools-assign-domain.md) | 託管或不託管用於身分驗證的公有網頁 | 使用者集區 | 關閉公有網頁並僅允許以 SDK 為基礎的身分驗證 | 網域 | [CreateUserPoolDomain](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolDomain.html)<br />建立任何使用者集區網域都會提供公有網頁。 | 
| [威脅防護](cognito-user-pool-settings-threat-protection.md) | 啟用或停用監控惡意活動或不安全密碼的跡象 | 使用者集區或應用程式用戶端 | 當使用者顯示入侵指標時， 可以自動封鎖登入或要求 MFA | 威脅防護 – 保護設定 | [SetRiskConfiguration](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetRiskConfiguration.html)<br />的參數會`SetRiskConfiguration`定義您的威脅防護設定。 | 

## 使用用戶端秘密保護機密用戶端
<a name="user-pool-security-best-practices-client-secret"></a>

用戶端秘密是與[應用程式用戶端](user-pool-settings-client-apps.md)相關聯的選用字串。對具有用戶端秘密的應用程式用戶端的所有身分驗證請求必須包含從使用者名稱、用戶端 ID 和用戶端秘密產生的[秘密雜湊](signing-up-users-in-your-app.md#cognito-user-pools-computing-secret-hash)。不知道用戶端秘密的人會從頭關閉您的應用程式。

不過，用戶端秘密有限制。如果您在公有用戶端軟體中內嵌用戶端秘密，您的用戶端秘密會開放檢查。這可讓您在應用程式用戶端中建立使用者、提交密碼重設請求，以及執行其他操作。只有在應用程式是唯一可存取秘密的實體時，才必須實作用戶端秘密。一般而言，這在伺服器端機密用戶端應用程式中是可行的。對於需要用戶端秘密的 [M2M 應用程式](cognito-user-pools-define-resource-servers.md)也是如此。將用戶端秘密存放在加密的本機儲存或 中 AWS Secrets Manager。切勿讓您的用戶端秘密出現在公有網際網路上。

## 保護其他秘密
<a name="user-pool-security-best-practices-manage-secrets"></a>

您使用 Amazon Cognito 使用者集區的身分驗證系統可能會處理私有資料、密碼和 AWS 登入資料。以下是處理應用程式可能存取之秘密的一些最佳實務。

**密碼**  
使用者登入您的應用程式時，可能會輸入密碼。Amazon Cognito 具有重新整理權杖，您的應用程式可以用來繼續過期的使用者工作階段，而無需新的密碼提示。請勿在本機儲存體中放置任何密碼或密碼雜湊。設計您的應用程式將密碼視為不透明，並僅將密碼傳遞至您的使用者集區。  
最佳實務是使用 [WebAuthn 通行金鑰](amazon-cognito-user-pools-authentication-flow-methods.md#amazon-cognito-user-pools-authentication-flow-methods-passkey)實作無密碼身分驗證。如果您必須實作密碼，請使用[安全遠端密碼 (SRP) 身分驗證流程](amazon-cognito-user-pools-authentication-flow-methods.md#amazon-cognito-user-pools-authentication-flow-methods-srp)和[多重要素驗證 (MFA)](amazon-cognito-user-pools-authentication-flow-methods.md#amazon-cognito-user-pools-authentication-flow-methods-mfa)。

**AWS 登入資料**  
管理身分驗證和使用者集區管理操作需要使用 AWS 登入資料進行身分驗證。若要在應用程式中實作這些操作，請授予[暫時 AWS 登入](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)資料的安全存取權。僅將登入資料存取權授予在您控制之伺服器元件上執行的應用程式。請勿將具有 AWS 登入資料的應用程式放在公有版本控制系統上，例如 GitHub。請勿在公有用戶端應用程式中編碼 AWS 登入資料。

**PKCE 程式碼驗證器**  
[Code Exchange 或 PKCE 的證明金鑰](using-pkce-in-authorization-code.md)適用於 OpenID Connect (OIDC) 授權碼授予您的使用者集區授權伺服器。應用程式在請求授權碼時，會與您的使用者集區共用程式碼驗證器秘密。若要交換權杖的授權碼，用戶端必須再次確認他們知道程式碼驗證程式。此實務可防止使用攔截的授權碼發出權杖。  
用戶端必須在每個授權請求中產生新的隨機程式碼驗證程式。使用靜態或可預測程式碼驗證器表示攻擊者只需要攔截硬式編碼驗證器和授權碼。設計您的應用程式，使其不會向使用者公開程式碼驗證器值。

## 使用者集區管理最低權限
<a name="user-pool-security-best-practices-least-privilege"></a>

IAM 政策可以定義主體對 Amazon Cognito 使用者集區管理和管理身分驗證操作的存取層級。例如：
+ 向 Web 伺服器授予使用管理 API 操作進行身分驗證的許可。
+ 向在 中管理使用者集區 AWS IAM Identity Center 的使用者 AWS 帳戶授予使用者集區維護和報告的許可。

Amazon Cognito 中的資源精細程度僅限於[兩種資源類型](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazoncognitoidentity.html#amazoncognitoidentity-resources-for-iam-policies)，用於 IAM 政策用途：使用者集區和身分集區。請注意，您無法套用管理個別應用程式用戶端的許可。設定使用者集區，了解您授予的許可在所有應用程式用戶端中都有效。當您的組織有多個應用程式租用戶，且您的安全模型需要在租用戶之間分離管理責任時，請[實作每個使用者集區一個租用戶的多租用戶](bp_user-pool-based-multi-tenancy.md)。

雖然您可以建立具有 等使用者身分驗證操作許可的 IAM 政策`InitiateAuth`，但這些許可沒有作用。[公有和字符授權的 API 操作](authentication-flows-public-server-side.md)不受 IAM 許可的約束。在可用的使用者集區身分驗證操作中，您只能將許可授予*管理*伺服器端操作，例如 `AdminInitiateAuth`。

您可以使用最低權限`Action`清單來限制使用者集區管理層級。下列範例政策適用於可以管理 IdPs、資源伺服器、應用程式用戶端和使用者集區網域，但不能管理使用者或使用者集區的管理員。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "UserPoolClientAdministrator",
      "Action": [
        "cognito-idp:CreateIdentityProvider",
        "cognito-idp:CreateManagedLoginBranding",
        "cognito-idp:CreateResourceServer",
        "cognito-idp:CreateUserPoolDomain",
        "cognito-idp:DeleteIdentityProvider",
        "cognito-idp:DeleteResourceServer",
        "cognito-idp:DeleteUserPoolDomain",
        "cognito-idp:DescribeIdentityProvider",
        "cognito-idp:DescribeManagedLoginBranding",
        "cognito-idp:DescribeManagedLoginBrandingByClient",
        "cognito-idp:DescribeResourceServer",
        "cognito-idp:DescribeUserPool",
        "cognito-idp:DescribeUserPoolClient",
        "cognito-idp:DescribeUserPoolDomain",
        "cognito-idp:GetIdentityProviderByIdentifier",
        "cognito-idp:GetUICustomization",
        "cognito-idp:ListIdentityProviders",
        "cognito-idp:ListResourceServers",
        "cognito-idp:ListUserPoolClients",
        "cognito-idp:ListUserPools",
        "cognito-idp:SetUICustomization",
        "cognito-idp:UpdateIdentityProvider",
        "cognito-idp:UpdateManagedLoginBranding",
        "cognito-idp:UpdateResourceServer",
        "cognito-idp:UpdateUserPoolClient",
        "cognito-idp:UpdateUserPoolDomain"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:cognito-idp:us-west-2:123456789012:userpool/us-west-2_EXAMPLE"
    }
  ]
}
```

------

下列範例政策會將使用者和群組管理和身分驗證授予伺服器端應用程式。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "UserAdminAuthN",
      "Action": [
        "cognito-idp:AdminAddUserToGroup",
        "cognito-idp:AdminConfirmSignUp",
        "cognito-idp:AdminCreateUser",
        "cognito-idp:AdminDeleteUser",
        "cognito-idp:AdminDeleteUserAttributes",
        "cognito-idp:AdminDisableProviderForUser",
        "cognito-idp:AdminDisableUser",
        "cognito-idp:AdminEnableUser",
        "cognito-idp:AdminForgetDevice",
        "cognito-idp:AdminGetDevice",
        "cognito-idp:AdminGetUser",
        "cognito-idp:AdminInitiateAuth",
        "cognito-idp:AdminLinkProviderForUser",
        "cognito-idp:AdminListDevices",
        "cognito-idp:AdminListGroupsForUser",
        "cognito-idp:AdminListUserAuthEvents",
        "cognito-idp:AdminRemoveUserFromGroup",
        "cognito-idp:AdminResetUserPassword",
        "cognito-idp:AdminRespondToAuthChallenge",
        "cognito-idp:AdminSetUserMFAPreference",
        "cognito-idp:AdminSetUserPassword",
        "cognito-idp:AdminSetUserSettings",
        "cognito-idp:AdminUpdateAuthEventFeedback",
        "cognito-idp:AdminUpdateDeviceStatus",
        "cognito-idp:AdminUpdateUserAttributes",
        "cognito-idp:AdminUserGlobalSignOut",
        "cognito-idp:AssociateSoftwareToken",
        "cognito-idp:ListGroups",
        "cognito-idp:ListUsers",
        "cognito-idp:ListUsersInGroup",
        "cognito-idp:RevokeToken",
        "cognito-idp:UpdateGroup",
        "cognito-idp:VerifySoftwareToken"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:cognito-idp:us-west-2:123456789012:userpool/us-west-2_EXAMPLE"
    }
  ]
}
```

------

## 保護和驗證字符
<a name="user-pool-security-best-practices-secure-tokens"></a>

字符可以包含對群組成員資格和使用者屬性的內部參考，您可能不想向最終使用者揭露這些屬性。請勿在本機儲存體中存放 ID 和存取權杖。重新整理字符會使用只有您的使用者集區可以存取的金鑰進行加密，並且對使用者和應用程式而言是不透明的。當使用者登出，或當您判斷基於安全考量而不需要保留使用者的工作階段時，[請撤銷重新整理權杖](token-revocation.md)。

使用存取權杖僅授權存取獨立驗證權杖有效和未過期的系統。如需驗證資源，請參閱[驗證 JSON Web 權杖](amazon-cognito-user-pools-using-tokens-verifying-a-jwt.md)。

## 決定您要信任的身分提供者
<a name="user-pool-security-best-practices-trusted-idps"></a>

當您使用 [SAML](cognito-user-pools-saml-idp.md) 或 [OIDC](cognito-user-pools-oidc-idp.md) 身分提供者 (IdPs) 設定使用者集區時，IdPs 可以建立新的使用者、設定使用者屬性，以及存取您的應用程式資源。SAML 和 OIDC 提供者通常用於business-to-business(B2B) 或企業案例，其中您或您的直接客戶控制提供者的成員資格和組態。

[社交提供者](cognito-user-pools-social-idp.md)會將使用者帳戶提供給網際網路上的任何人，並且比企業提供者更少。只有在您準備好允許公有客戶登入和存取應用程式中的資源時，才能在您的應用程式用戶端中啟用社交 IdPs。

## 了解範圍對存取使用者設定檔的影響
<a name="user-pool-security-best-practices-scopes"></a>

您可以向使用者集區授權伺服器請求身分驗證請求中的存取控制範圍。這些範圍可以授予使用者外部資源的存取權，也可以授予使用者檢視和修改自己的使用者設定檔的存取權。設定您的應用程式用戶端，以支援應用程式操作所需的最低範圍。

`aws.cognito.signin.user.admin` 範圍存在於 SDK 身分驗證使用 [InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) 等操作發行的所有存取字符中。它被指定用於應用程式中的使用者設定檔自助服務操作。您也可以向授權伺服器請求此範圍。權杖授權的操作需要此範圍，例如 [UpdateUserAttributes](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserAttributes.html) 和 [GetUser](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUser.html)。這些操作的效果受限於您應用程式用戶端的讀取和寫入許可。

`openid`、`email`、 `profile`和 `phone`範圍會授權請求給使用者集區授權伺服器上[userInfo 端點](userinfo-endpoint.md)的 。它們定義端點可以傳回的屬性。在沒有其他`openid`範圍的情況下請求時，範圍會傳回所有可用的屬性，但當您在請求中請求更多範圍時，回應會縮小到其他範圍所代表的屬性。此`openid`範圍也會指出 ID 字符的請求；當您從對 的請求中省略此範圍時[授權端點](authorization-endpoint.md)，Amazon Cognito 只會發出存取字符，並在適用時發出重新整理字符。如需詳細資訊，請參閱《》**中的 OpenID Connect 範圍**[應用程式用戶端條款](user-pool-settings-client-apps.md#cognito-user-pools-app-idp-settings-about)。

## 清理使用者屬性的輸入
<a name="user-pool-security-best-practices-sanitize-inputs"></a>

最終可能做為交付方法和使用者名稱的使用者屬性，例如 `email`，具有[格式限制](user-pool-settings-attributes.md#cognito-user-pools-standard-attributes)。其他屬性可以有字串、布林值或數字資料類型。字串屬性值支援各種輸入。設定您的應用程式以防止嘗試將不需要的資料寫入您的使用者目錄或 Amazon Cognito 提供給使用者的訊息。將使用者提交的字串屬性值提交至 Amazon Cognito 之前，請對應用程式中的使用者提交字串屬性值執行用戶端驗證。

使用者集區會根據您指定的屬性映射，將屬性從 IdPs[映射](cognito-user-pools-specifying-attribute-mapping.md)到您的使用者集區。僅將安全且可預測的 IdP 屬性映射至使用者集區字串屬性。