

 適用於 .NET 的 AWS SDK V3 已進入維護模式。

我們建議您遷移至 [適用於 .NET 的 AWS SDK V4](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/welcome.html)。如需如何遷移的其他詳細資訊和資訊，請參閱我們的[維護模式公告](https://aws.amazon.com/blogs/developer/aws-sdk-for-net-v3-maintenance-mode-announcement/)。

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

# 使用 Amazon Cognito 驗證使用者
<a name="cognito-apis-intro"></a>

**注意**  
本主題中的資訊專屬於以 .NET Framework 和 3.3 適用於 .NET 的 AWS SDK 版及更早版本為基礎的專案。

使用 Amazon Cognito Identity，您可以為使用者建立唯一身分，並對其進行身分驗證，以安全地存取您的 AWS 資源，例如 Amazon S3 或 Amazon DynamoDB。Amazon Cognito Identity 支援公有身分提供者，例如 Amazon、Facebook、Twitter/Digits、Google 或任何 OpenID Connect 相容提供者，以及未驗證的身分。Amazon Cognito 也支援[開發人員驗證的身分](https://aws.amazon.com/blogs/mobile/amazon-cognito-announcing-developer-authenticated-identities/)，可讓您使用自己的後端身分驗證程序註冊和驗證使用者，同時仍使用 Amazon Cognito Sync 同步使用者資料和存取 AWS 資源。

如需 [Amazon Cognito](https://aws.amazon.com/cognito/) 的詳細資訊，請參閱《[Amazon Cognito 開發人員指南](https://docs.aws.amazon.com/cognito/latest/developerguide/)》。

下列程式碼範例示範如何輕鬆使用 Amazon Cognito Identity。此[憑證提供者](cognito-creds-provider.md)範例示範如何建立和驗證使用者身分。此[CognitoAuthentication 延伸程式庫](cognito-authentication-extension.md)範例示範如何使用 CognitoAuthentication 延伸程式庫來驗證 Amazon Cognito 使用者集區。

**Topics**
+ [憑證提供者](cognito-creds-provider.md)
+ [CognitoAuthentication 延伸程式庫](cognito-authentication-extension.md)

# Amazon Cognito 登入資料提供者
<a name="cognito-creds-provider"></a>

**注意**  
本主題中的資訊專屬於以 .NET Framework 和 3.3 適用於 .NET 的 AWS SDK 版及更早版本為基礎的專案。

 `Amazon.CognitoIdentity.CognitoAWSCredentials`位於 [AWSSDK.CognitoIdentity](https://www.nuget.org/packages/AWSSDK.CognitoIdentity/) NuGet 套件中的 是登入資料物件，使用 Amazon Cognito 和 AWS Security Token Service (AWS STS) 擷取登入資料以進行 AWS 呼叫。

設定 `CognitoAWSCredentials` 的第一步是建立「身分集區」。身分集區是您的帳戶專屬的使用者身分資訊存放區。此資訊可跨用戶端平台、裝置和作業系統擷取，因此，如果使用者一開始是在手機上使用您的應用程式，之後再切換到平板電腦，所保存的應用程式資訊仍然可供該使用者使用。您可以從 Amazon Cognito 主控台建立新的身分集區。如果您使用主控台，它還會提供您需要的其他資訊：
+ 您的帳號是 12 位數字的號碼，例如 123456789012，是您帳戶專有。
+ 未驗證角色 ARN - 未驗證的使用者將擔任的角色。例如，此角色可提供您資料的唯讀許可。
+ 已驗證的角色 ARN - 已驗證的使用者將擔任的角色。此角色可提供您資料更多許可。

## 設定 CognitoAWSCredentials
<a name="set-up-cognitoawscredentials"></a>

下列程式碼範例示範如何設定 `CognitoAWSCredentials`，然後您可以使用它以未經驗證的使用者身分呼叫 Amazon S3。這可讓您只使用所需的最少量資料來驗證使用者身分。使用者權限由角色控制，因此您可以依需要設定存取權。

```
CognitoAWSCredentials credentials = new CognitoAWSCredentials(
    accountId,        // Account number
    identityPoolId,   // Identity pool ID
    unAuthRoleArn,    // Role for unauthenticated users
    null,             // Role for authenticated users, not set
    region);
using (var s3Client = new AmazonS3Client(credentials))
{
    s3Client.ListBuckets();
}
```

## 使用 AWS 做為未驗證的使用者
<a name="use-aws-as-an-unauthenticated-user"></a>

下列程式碼範例示範如何以未經驗證的使用者 AWS 身分開始使用 ，然後透過 Facebook 進行身分驗證，並更新登入資料以使用 Facebook 登入資料。使用此方法，您便可已驗證的角色授與不同功能給已驗證身分的使用者。例如您的手機應用程式允許使用者匿名檢視內容，如果使用一或多個設定的提供者身分登入的話，還可讓他們張貼文章。

```
CognitoAWSCredentials credentials = new CognitoAWSCredentials(
    accountId, identityPoolId,
    unAuthRoleArn,    // Role for unauthenticated users
    authRoleArn,      // Role for authenticated users
    region);
using (var s3Client = new AmazonS3Client(credentials))
{
    // Initial use will be unauthenticated
    s3Client.ListBuckets();

    // Authenticate user through Facebook
    string facebookToken = GetFacebookAuthToken();

    // Add Facebook login to credentials. This clears the current AWS credentials
    // and retrieves new AWS credentials using the authenticated role.
    credentials.AddLogin("graph.facebook.com", facebookAccessToken);

    // This call is performed with the authenticated role and credentials
    s3Client.ListBuckets();
}
```

如果您使用 `AmazonCognitoSyncClient` (屬 適用於 .NET 的 AWS SDK的一部分)，`CognitoAWSCredentials` 物件甚至能提供更多功能。如果您同時使用 `AmazonCognitoSyncClient`和 `CognitoAWSCredentials`，則不需要在使用 呼叫 時指定 `IdentityPoolId`和 `IdentityId` 屬性`AmazonCognitoSyncClient`。這些屬性會自動從 `CognitoAWSCredentials` 填入。下一個程式碼範例將對此做說明，並且提供一個事件，只要適用於 `CognitoAWSCredentials` 的 `IdentityId` 有變動時就會通知您。在某些情況下，例如從未驗證使用者變更為已驗證使用者時，`IdentityId` 即可變更。

```
CognitoAWSCredentials credentials = GetCognitoAWSCredentials();

// Log identity changes
credentials.IdentityChangedEvent += (sender, args) =>
{
    Console.WriteLine("Identity changed: [{0}] => [{1}]", args.OldIdentityId, args.NewIdentityId);
};

using (var syncClient = new AmazonCognitoSyncClient(credentials))
{
    var result = syncClient.ListRecords(new ListRecordsRequest
    {
        DatasetName = datasetName
        // No need to specify these properties
        //IdentityId = "...",
        //IdentityPoolId = "..."        
    });
}
```

# Amazon CognitoAuthentication 延伸程式庫範例
<a name="cognito-authentication-extension"></a>

**注意**  
本主題中的資訊專屬於以 .NET Framework 和 3.3 適用於 .NET 的 AWS SDK 版及更早版本為基礎的專案。

CognitoAuthentication 延伸程式庫位於 [Amazon.Extensions.CognitoAuthentication](https://www.nuget.org/packages/Amazon.Extensions.CognitoAuthentication/) NuGet 套件中，可簡化 .NET Core 和 Xamarin 開發人員的 Amazon Cognito 使用者集區的身分驗證程序。程式庫建置在 Amazon Cognito Identity Provider API 之上，以建立和傳送使用者身分驗證 API 呼叫。

## 使用 CognitoAuthentication 延伸程式庫
<a name="using-the-cognitoauthentication-extension-library"></a>

Amazon Cognito 有一些標準身分驗證流程的內建 `AuthFlow` 和 `ChallengeName`值，可透過安全遠端密碼 (SRP) 驗證使用者名稱和密碼。如需有關驗證流量的詳細資訊，請參閱 [Amazon Cognito 使用者集區身分驗證流程 ](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html)。

以下範例需要這些 `using` 陳述式：

```
// Required for all examples
using System;
using Amazon;
using Amazon.CognitoIdentity;
using Amazon.CognitoIdentityProvider;
using Amazon.Extensions.CognitoAuthentication;
using Amazon.Runtime;
// Required for the GetS3BucketsAsync example
using Amazon.S3;
using Amazon.S3.Model;
```

### 使用基本身分驗證
<a name="use-basic-authentication"></a>

使用 [AnonymousAWSCredentials](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Runtime/TAnonymousAWSCredentials.html) 建立 [AmazonCognitoIdentityProviderClient](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CognitoIdentityProvider/TCognitoIdentityProviderClient.html)，這不需要簽署的請求。您不需要提供一個區域。如果未提供區域，基本程式碼會呼叫 `FallbackRegionFactory.GetRegionEndpoint()`。建立 `CognitoUserPool` 和 `CognitoUser` 物件。以 `InitiateSrpAuthRequest` 呼叫 `StartWithSrpAuthAsync` 的方法，其中包含使用者密碼。

```
public static async void GetCredsAsync()
{
    AmazonCognitoIdentityProviderClient provider =
        new AmazonCognitoIdentityProviderClient(new Amazon.Runtime.AnonymousAWSCredentials());
    CognitoUserPool userPool = new CognitoUserPool("poolID", "clientID", provider);
    CognitoUser user = new CognitoUser("username", "clientID", userPool, provider);
    InitiateSrpAuthRequest authRequest = new InitiateSrpAuthRequest()
    {
        Password = "userPassword"
    };

    AuthFlowResponse authResponse = await user.StartWithSrpAuthAsync(authRequest).ConfigureAwait(false);
    accessToken = authResponse.AuthenticationResult.AccessToken;

}
```

### 利用挑戰進行驗證
<a name="authenticate-with-challenges"></a>

繼續挑戰驗證流程，例如使用 NewPasswordRequired 和 Multi-Factor Authentication (MFA)，也更簡易。唯一的需求是 CognitoAuthentication 物件、SRP 使用者的密碼和下次挑戰需要的資訊，需要在使用者輸入後取得提示。以下程式碼會在驗證流程中顯示一個方式來檢查挑戰類型、取得 MFA 的適當回應和 NewPasswordRequired 挑戰。

如同之前提出基本驗證請求，並且 `await` `AuthFlowResponse`。當透過傳回的 `AuthenticationResult` 物件收到循環回應時。如果 `ChallengeName` 類型為 `NEW_PASSWORD_REQUIRED`，呼叫 `RespondToNewPasswordRequiredAsync` 方法。

```
public static async void GetCredsChallengesAsync()
{
    AmazonCognitoIdentityProviderClient provider = 
        new AmazonCognitoIdentityProviderClient(new Amazon.Runtime.AnonymousAWSCredentials());
    CognitoUserPool userPool = new CognitoUserPool("poolID", "clientID", provider);
    CognitoUser user = new CognitoUser("username", "clientID", userPool, provider);
    InitiateSrpAuthRequest authRequest = new InitiateSrpAuthRequest(){
        Password = "userPassword"
    };

    AuthFlowResponse authResponse = await user.StartWithSrpAuthAsync(authRequest).ConfigureAwait(false);

    while (authResponse.AuthenticationResult == null)
    {
        if (authResponse.ChallengeName == ChallengeNameType.NEW_PASSWORD_REQUIRED)
        {
            Console.WriteLine("Enter your desired new password:");
            string newPassword = Console.ReadLine();

            authResponse = await user.RespondToNewPasswordRequiredAsync(new RespondToNewPasswordRequiredRequest()
            {
                SessionID = authResponse.SessionID,
                NewPassword = newPassword
            });
            accessToken = authResponse.AuthenticationResult.AccessToken;
        }
        else if (authResponse.ChallengeName == ChallengeNameType.SMS_MFA)
        {
            Console.WriteLine("Enter the MFA Code sent to your device:");
            string mfaCode = Console.ReadLine();

            AuthFlowResponse mfaResponse = await user.RespondToSmsMfaAuthAsync(new RespondToSmsMfaRequest()
            {
                SessionID = authResponse.SessionID,
                MfaCode = mfaCode

            }).ConfigureAwait(false);
            accessToken = authResponse.AuthenticationResult.AccessToken;
        }
        else
        {
            Console.WriteLine("Unrecognized authentication challenge.");
            accessToken = "";
            break;
        }
    }

    if (authResponse.AuthenticationResult != null)
    {
        Console.WriteLine("User successfully authenticated.");
    }
    else
    {
        Console.WriteLine("Error in authentication process.");
    }
 
}
```

### 身分驗證後使用 AWS 資源
<a name="use-aws-resources-after-authentication"></a>

使用 CognitoAuthentication 程式庫驗證使用者後，下一步是允許使用者存取適當的 AWS 資源。若要這樣做，您必須透過 Amazon Cognito 聯合身分主控台建立身分集區。透過指定您建立做為提供者的 Amazon Cognito 使用者集區，使用其 poolID 和 clientID，您可以允許 Amazon Cognito 使用者集區使用者存取 AWS 連接到您帳戶的資源。您也可以指定不同的角色，以啟用這兩種未經驗證及經過驗證的使用者存取不同的資源。您可以在 IAM 主控台變更這些規則，其中您可以新增或移除附加政策之角色的 **Action (動作)** 欄位的許可。然後，使用適當的身分集區、使用者集區和 Amazon Cognito 使用者資訊，您可以呼叫不同的 AWS 資源。下列範例顯示透過 SRP 驗證的使用者，存取關聯身分集區角色允許的不同 Amazon S3 儲存貯體

```
public async void GetS3BucketsAsync()
{
    var provider = new AmazonCognitoIdentityProviderClient(new AnonymousAWSCredentials());
    CognitoUserPool userPool = new CognitoUserPool("poolID", "clientID", provider);
    CognitoUser user = new CognitoUser("username", "clientID", userPool, provider);

    string password = "userPassword";

    AuthFlowResponse context = await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest()
    {
        Password = password
    }).ConfigureAwait(false);

    CognitoAWSCredentials credentials =
        user.GetCognitoAWSCredentials("identityPoolID", RegionEndpoint.< YourIdentityPoolRegion >);

    using (var client = new AmazonS3Client(credentials))
    {
        ListBucketsResponse response =
            await client.ListBucketsAsync(new ListBucketsRequest()).ConfigureAwait(false);

        foreach (S3Bucket bucket in response.Buckets)
        {
            Console.WriteLine(bucket.BucketName);
        }
    }
}
```

## 更多身分驗證選項
<a name="more-authentication-options"></a>

除了 SRP、NewPasswordRequired 和 MFA，CognitoAuthentication 擴展程式庫提供更輕鬆的驗證流程：
+ 自訂 - 以呼叫 `StartWithCustomAuthAsync(InitiateCustomAuthRequest customRequest)` 起始 
+ RefreshToken - 以呼叫 `StartWithRefreshTokenAuthAsync(InitiateRefreshTokenAuthRequest refreshTokenRequest)` 起始 
+ RefreshTokenSRP - 以呼叫 `StartWithRefreshTokenAuthAsync(InitiateRefreshTokenAuthRequest refreshTokenRequest)` 起始 
+ AdminNoSRP - 以呼叫 `StartWithAdminNoSrpAuthAsync(InitiateAdminNoSrpAuthRequest adminAuthRequest)` 起始 

根據您要的流程呼叫適當的方法。然後，當每個方法呼叫的 `AuthFlowResponse` 物件中顯示挑戰時，繼續提示使用者挑戰的存在。同時呼叫適當的回應方法，例如 `RespondToSmsMfaAuthAsync` 用於 MFA 挑戰，`RespondToCustomAuthAsync` 用於自訂挑戰。