

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在应用程序中收集威胁防护的数据
<a name="user-pool-settings-viewing-threat-protection-app"></a>

Amazon Cognito [自适应身份验证](cognito-user-pool-settings-adaptive-authentication.md)根据用户登录尝试的上下文详细信息评估账户盗用尝试的风险等级。您的应用程序必须向 API 请求添加*上下文数据*，这样 Amazon Cognito 威胁防护功能才能更准确地评估风险。上下文数据是诸如 IP 地址、浏览器代理、设备信息和请求标头之类的信息，这些信息提供有关用户如何连接到用户池的上下文信息。

向 Amazon Cognito 提交此上下文的应用程序的核心责任是向用户池发送身份验证请求中的一个 `EncodedData` 参数。要将这些数据添加到您的请求中，您可以使用软件开发工具包实现 Amazon Cognito，该软件开发工具包可以自动为您生成这些信息，也可以实现一个适用于 JavaScript iOS 或 Android 的模块来收集这些数据。必须实现直接向 Amazon Cognito 发出请求的@@ *仅限客户端*的应用程序。 AWS Amplify SDKs具有中间服务器或 API 组件的*客户端-服务器*应用程序必须实施单独的 SDK 模块。

在以下情况下，您的身份验证前端无需任何额外配置即可管理用户上下文数据的收集：
+ 托管登录会自动收集上下文数据并将其提交给威胁防护。
+ 所有 AWS Amplify 库的身份验证方法中都内置了上下文数据集合。

## 使用 Amplify 在仅限客户端的应用程序中提交用户上下文数据
<a name="user-pool-settings-viewing-threat-protection-app-amplify"></a>

![\[Amplify 应用程序中收集数据以进行威胁防护的概览图。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/user-pools-asf-amplify-data-collection.png)


Amplify SDKs 支持直接通过 Amazon Cognito 进行身份验证的移动客户端。此类客户端直接向 Amazon Cognito 公共 API 操作发出 API 请求。默认情况下，Amplify 客户端会自动收集上下文数据以进行威胁防护。

带的 Amplify 应用程序是个 JavaScript 例外。它们需要添加一个用于收集用户上下文数据的[JavaScript 模块](#user-pool-settings-viewing-threat-protection-app-additional-resources-js)。

通常，此配置中的应用程序使用未经身份验证的 API 操作，例如[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)和。[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)该[UserContextData](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UserContextDataType.html)对象有助于更准确地评估这些操作的风险。Amplify SDKs 将设备和会话信息添加到的`EncodedData`参数中。`UserContextData`

## 在客户端-服务器应用程序中收集上下文数据
<a name="user-pool-settings-viewing-threat-protection-app-server-side"></a>

某些应用程序的前端层用于收集用户身份验证数据，应用程序的后端层用于将身份验证请求提交到 Amazon Cognito。在由微服务支持的 Web 服务器和应用程序中，这是一种常见的架构。在这些应用程序中，必须导入公共上下文数据收集库。

![\[中包含威胁防护上下文数据的服务器端身份验证概述。 JavaScript\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/user-pools-asf-non-amplify-data-collection.png)


通常，此配置中的应用服务器使用经过身份验证的 API 操作，例如[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)和[AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html)。该[ContextData](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html#CognitoUserPools-AdminInitiateAuth-request-ContextData)对象可帮助 Amazon Cognito 更准确地评估这些操作的风险。`ContextData` 的内容是您的前端传递给服务器的编码数据，以及用户向服务器发出的 HTTP 请求中的其他详细信息。这些额外的上下文详细信息（例如 HTTP 标头和 IP 地址）为您的应用程序服务器提供了用户环境的特性。

您的应用服务器也可能使用未经身份验证的 API 操作（如[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)和）进行登录。[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)该[UserContextData](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html#CognitoUserPools-InitiateAuth-request-UserContextData)对象为这些操作中的威胁防护风险分析提供信息。可用的公共上下文数据收集库中的操作将安全信息添加到身份验证请求的 `EncodedData` 参数中。此外，将您的用户池配置为接受其他上下文数据，并将用户的源 IP 添加到 `UserContextData` 的 `IpAddress` 参数中。

**将上下文数据添加到客户端-服务器应用程序**

1. 在您的前端应用程序中，使用 iO [S、Android 或 JavaScript ](#user-pool-settings-viewing-threat-protection-app-additional-resources)模块从客户端收集经过编码的上下文数据。

1. 将编码后的数据和身份验证请求的详细信息传递给应用程序服务器。

1. 在应用程序服务器中，从 HTTP 请求中提取用户的 IP 地址、相关 HTTP 标头、请求的服务器名称和请求的路径。将这些值填充到你向 Amazon Cognito 发出 API 请求的[ContextData](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html#CognitoUserPools-AdminInitiateAuth-request-ContextData)参数中。

1. 使用您的 SDK 模块收集的已编码设备数据填充您的 API 请求中的 `ContextData` 的 `EncodedData` 参数。将此上下文数据添加到身份验证请求中。

## 客户端-服务器应用程序的上下文数据库
<a name="user-pool-settings-viewing-threat-protection-app-additional-resources"></a>

### JavaScript
<a name="user-pool-settings-viewing-threat-protection-app-additional-resources-js"></a>

`amazon-cognito-advanced-security-data.min.js` 模块收集了 `EncodedData`，您可以将其传递给应用程序服务器。

将该`amazon-cognito-advanced-security-data.min.js`模块添加到您的 JavaScript 配置中。`<region>`替换为以下 AWS 区域 列表中的：`us-east-1`、`us-east-2`、`us-west-2``eu-west-1`、`eu-west-2`、或`eu-central-1`。

```
<script src="https://amazon-cognito-assets.<region>.amazoncognito.com/amazon-cognito-advanced-security-data.min.js"></script>
```

要生成可在`EncodedData`参数中使用的`encodedContextData`对象，请将以下内容添加到您的 JavaScript 应用程序源中：

```
var encodedContextData = AmazonCognitoAdvancedSecurityData.getData(_username, _userpoolId, _userPoolClientId);
```

### iOS/Swift
<a name="user-pool-settings-viewing-threat-protection-app-additional-resources-ios"></a>

要生成上下文数据，iOS 应用程序可以集成适用于 iO [S 的移动 SDK](https://github.com/aws-amplify/aws-sdk-ios/tree/main) 模块 [AWSCognitoIdentityProviderASF](https://github.com/aws-amplify/aws-sdk-ios/tree/main/AWSCognitoIdentityProviderASF)。

要收集经过编码的上下文数据以进行威胁防护，请将以下代码段添加到您的应用程序中：

```
import AWSCognitoIdentityProviderASF

let deviceId = getDeviceId()
let encodedContextData = AWSCognitoIdentityProviderASF.userContextData(
                            userPoolId, 
                            username: username, 
                            deviceId: deviceId, 
                            userPoolClientId: userPoolClientId)
                                
/**
 * Reuse DeviceId from keychain or generate one for the first time.
 */
func getDeviceId() -> String {
    let deviceIdKey = getKeyChainKey(namespace: userPoolId, key: "AWSCognitoAuthAsfDeviceId")
    
   if let existingDeviceId = self.keychain.string(forKey: deviceIdKey) {
        return existingDeviceId
    }

    let newDeviceId = UUID().uuidString
    self.keychain.setString(newDeviceId, forKey: deviceIdKey)
    return newDeviceId
}

/**
 * Get a namespaced keychain key given a namespace and key
 */    
func getKeyChainKey(namespace: String, key: String) -> String {
    return "\(namespace).\(key)"
}
```

### Android
<a name="user-pool-settings-viewing-threat-protection-app-additional-resources-android"></a>

要生成上下文数据，安卓应用可以集成[适用于安卓的移动 SDK](https://github.com/aws-amplify/aws-sdk-android/tree/main) 模块 [aws-android-sdk-cognitoidentityprovider-asf](https://github.com/aws-amplify/aws-sdk-android/tree/main/aws-android-sdk-cognitoidentityprovider-asf)。

要收集经过编码的上下文数据以进行威胁防护，请将以下代码段添加到您的应用程序中：

```
UserContextDataProvider provider = UserContextDataProvider.getInstance();
// context here is android application context.
String encodedContextData = provider.getEncodedContextData(context, username, userPoolId, userPoolClientId);
```