Skip to content

Commit

Permalink
.NET v3: Updates and fixes to Cognito MVP. (#5336)
Browse files Browse the repository at this point in the history
* Updates and fixes to Cognito MVP.

* Updating logic.
  • Loading branch information
rlhagerm authored Aug 30, 2023
1 parent 992358f commit 6a3ab3b
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 100 deletions.
11 changes: 0 additions & 11 deletions .doc_gen/metadata/cognito-identity-provider_metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -697,15 +697,6 @@ cognito-identity-provider_RespondToAuthChallenge:
synopsis: respond to &COG; SRP authentication challenges.
category:
languages:
.NET:
versions:
- sdk_version: 3
github: dotnetv3/Cognito
sdkguide:
excerpts:
- description:
snippet_tags:
- Cognito.dotnetv3.RespondToAuthChallenge
Python:
versions:
- sdk_version: 3
Expand Down Expand Up @@ -764,10 +755,8 @@ cognito-identity-provider_Scenario_SignUpUserWithMfa:
excerpts:
- description:
snippet_tags:
- Cognito.dotnetv3.Usings
- Cognito.dotnetv3.Main
- Cognito.dotnetv3.CognitoWrapper
- Cognito.dotnetv3.UIMethods
Kotlin:
versions:
- sdk_version: 1
Expand Down
73 changes: 33 additions & 40 deletions dotnetv3/Cognito/Actions/CognitoWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public async Task<List<UserPoolDescriptionType>> ListUserPoolsAsync()
/// <summary>
/// Get a list of users for the Amazon Cognito user pool.
/// </summary>
/// <param name="userPoolId">The user pool Id.</param>
/// <param name="userPoolId">The user pool ID.</param>
/// <returns>A list of users.</returns>
public async Task<List<UserType>> ListUsersAsync(string userPoolId)
{
Expand All @@ -70,57 +70,43 @@ public async Task<List<UserType>> ListUsersAsync(string userPoolId)
// snippet-end:[Cognito.dotnetv3.ListUsers]

// snippet-start:[Cognito.dotnetv3.AdminRespondToAuthChallenge]
public async Task<AuthenticationResultType> AdminRespondToAuthChallengeAsync(string userPoolId, string userName, string clientId, string mfaCode, string session)
{
var challengeResponses = new Dictionary<string, string>();
challengeResponses.Add("USERNAME", userName);
challengeResponses.Add("SOFTWARE_TOKEN_MFA_CODE", mfaCode);

var request = new AdminRespondToAuthChallengeRequest
{
ClientId = clientId,
UserPoolId = userPoolId,
ChallengeResponses = challengeResponses,
Session = session
};

var response = await _cognitoService.AdminRespondToAuthChallengeAsync(request);
return response.AuthenticationResult;
}

// snippet-end:[Cognito.dotnetv3.AdminRespondToAuthChallenge]

// snippet-start:[Cognito.dotnetv3.RespondToAuthChallenge]
/// <summary>
/// Respond to an authentication challenge.
/// Respond to an admin authentication challenge.
/// </summary>
/// <param name="userName">The name of the user.</param>
/// <param name="clientId">The client Id.</param>
/// <param name="clientId">The client ID.</param>
/// <param name="mfaCode">The multi-factor authentication code.</param>
/// <param name="session">The current application session.</param>
/// <returns>An async Task.</returns>
public async Task<AuthenticationResultType> RespondToAuthChallengeAsync(string userName, string clientId, string mfaCode, string session)
/// <param name="clientId">The user pool ID.</param>
/// <returns>The result of the authentication response.</returns>
public async Task<AuthenticationResultType> AdminRespondToAuthChallengeAsync(
string userName,
string clientId,
string mfaCode,
string session,
string userPoolId)
{
Console.WriteLine("SOFTWARE_TOKEN_MFA challenge is generated");

var challengeResponses = new Dictionary<string, string>();
challengeResponses.Add("USERNAME", userName);
challengeResponses.Add("SOFTWARE_TOKEN_MFA_CODE", mfaCode);

var respondToAuthChallengeRequest = new RespondToAuthChallengeRequest
var respondToAuthChallengeRequest = new AdminRespondToAuthChallengeRequest
{
ChallengeName = ChallengeNameType.SOFTWARE_TOKEN_MFA,
ClientId = clientId,
ChallengeResponses = challengeResponses,
Session = session
Session = session,
UserPoolId = userPoolId,
};

var response = await _cognitoService.RespondToAuthChallengeAsync(respondToAuthChallengeRequest);
Console.WriteLine($"Response to Authentication {response.AuthenticationResult}");
var response = await _cognitoService.AdminRespondToAuthChallengeAsync(respondToAuthChallengeRequest);
Console.WriteLine($"Response to Authentication {response.AuthenticationResult.TokenType}");
return response.AuthenticationResult;
}

// snippet-end:[Cognito.dotnetv3.RespondToAuthChallenge]
// snippet-end:[Cognito.dotnetv3.AdminRespondToAuthChallenge]

// snippet-start:[Cognito.dotnetv3.VerifySoftwareToken]
/// <summary>
Expand Down Expand Up @@ -149,7 +135,7 @@ public async Task<VerifySoftwareTokenResponseType> VerifySoftwareTokenAsync(stri
/// Get an MFA token to authenticate the user with the authenticator.
/// </summary>
/// <param name="session">The session name.</param>
/// <returns>Returns the session name.</returns>
/// <returns>The session name.</returns>
public async Task<string> AssociateSoftwareTokenAsync(string session)
{
var softwareTokenRequest = new AssociateSoftwareTokenRequest
Expand All @@ -160,14 +146,22 @@ public async Task<string> AssociateSoftwareTokenAsync(string session)
var tokenResponse = await _cognitoService.AssociateSoftwareTokenAsync(softwareTokenRequest);
var secretCode = tokenResponse.SecretCode;

Console.Write("Enter the following token into the authenticator: {secretCode}");
Console.WriteLine($"Use the following secret code to set up the authenticator: {secretCode}");

return tokenResponse.Session;
}

// snippet-end:[Cognito.dotnetv3.AssociateSoftwareToken]

// snippet-start:[Cognito.dotnetv3.AdminInitiateAuth]
/// <summary>
/// Initiate an admin auth request.
/// </summary>
/// <param name="clientId">The client ID to use.</param>
/// <param name="userPoolId">The ID of the user pool.</param>
/// <param name="userName">The username to authenticate.</param>
/// <param name="password">The user's password.</param>
/// <returns>The session to use in challenge-response.</returns>
public async Task<string> AdminInitiateAuthAsync(string clientId, string userPoolId, string userName, string password)
{
var authParameters = new Dictionary<string, string>();
Expand All @@ -179,7 +173,7 @@ public async Task<string> AdminInitiateAuthAsync(string clientId, string userPoo
ClientId = clientId,
UserPoolId = userPoolId,
AuthParameters = authParameters,
AuthFlow = AuthFlowType.USER_PASSWORD_AUTH,
AuthFlow = AuthFlowType.ADMIN_USER_PASSWORD_AUTH,
};

var response = await _cognitoService.AdminInitiateAuthAsync(request);
Expand All @@ -194,7 +188,7 @@ public async Task<string> AdminInitiateAuthAsync(string clientId, string userPoo
/// <param name="clientId">The client Id of the application.</param>
/// <param name="userName">The name of the user who is authenticating.</param>
/// <param name="password">The password for the user who is authenticating.</param>
/// <returns>The response from the call to InitiateAuthAsync.</returns>
/// <returns>The response from the initiate auth request.</returns>
public async Task<InitiateAuthResponse> InitiateAuthAsync(string clientId, string userName, string password)
{
var authParameters = new Dictionary<string, string>();
Expand All @@ -214,7 +208,6 @@ public async Task<InitiateAuthResponse> InitiateAuthAsync(string clientId, strin

return response;
}

// snippet-end:[Cognito.dotnetv3.InitiateAuth]

// snippet-start:[Cognito.dotnetv3.ConfirmSignUp]
Expand All @@ -224,7 +217,7 @@ public async Task<InitiateAuthResponse> InitiateAuthAsync(string clientId, strin
/// <param name="clientId">The Id of this application.</param>
/// <param name="code">The confirmation code sent to the user.</param>
/// <param name="userName">The username.</param>
/// <returns></returns>
/// <returns>True if successful.</returns>
public async Task<bool> ConfirmSignupAsync(string clientId, string code, string userName)
{
var signUpRequest = new ConfirmSignUpRequest
Expand Down Expand Up @@ -274,7 +267,7 @@ public async Task<bool> ConfirmDeviceAsync(string accessToken, string deviceKey,
/// </summary>
/// <param name="clientId">The Id of the client application.</param>
/// <param name="userName">The username of user who will receive the code.</param>
/// <returns></returns>
/// <returns>The delivery details.</returns>
public async Task<CodeDeliveryDetailsType> ResendConfirmationCodeAsync(string clientId, string userName)
{
var codeRequest = new ResendConfirmationCodeRequest
Expand All @@ -298,7 +291,7 @@ public async Task<CodeDeliveryDetailsType> ResendConfirmationCodeAsync(string cl
/// </summary>
/// <param name="userName">The name of the user.</param>
/// <param name="poolId">The Id of the Amazon Cognito user pool.</param>
/// <returns></returns>
/// <returns>Async task.</returns>
public async Task<UserStatusType> GetAdminUserAsync(string userName, string poolId)
{
AdminGetUserRequest userRequest = new AdminGetUserRequest
Expand All @@ -324,7 +317,7 @@ public async Task<UserStatusType> GetAdminUserAsync(string userName, string pool
/// <param name="password">The user's password.</param>
/// <param name="email">The email address of the user.</param>
/// <returns>A Boolean value indicating whether the user was confirmed.</returns>
public async Task<bool> SignUpAsync(string clientId, string userName, string password, String email)
public async Task<bool> SignUpAsync(string clientId, string userName, string password, string email)
{
var userAttrs = new AttributeType
{
Expand Down
51 changes: 34 additions & 17 deletions dotnetv3/Cognito/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!--Generated by WRITEME on 2023-04-25 16:01:31.041958 (UTC)-->
<!--Generated by WRITEME on 2023-08-28 16:45:43.695374 (UTC)-->
# Amazon Cognito Identity Provider code examples for the SDK for .NET

## Overview
Expand All @@ -24,7 +24,7 @@ Shows how to use the AWS SDK for .NET to work with Amazon Cognito Identity Provi

### Prerequisites

For prerequisites, see the [README](../README.md#Prerequisites) in the `dotnetv3` folder.
For prerequisites, see the [README](README.md#Prerequisites) in the `dotnetv3` folder.


<!--custom.prerequisites.start-->
Expand All @@ -44,43 +44,53 @@ the scenario.

Code excerpts that show you how to call individual service functions.

* [Confirm a user](Actions/CognitoWrapper.cs#L220) (`ConfirmSignUp`)
* [Confirm an MFA device for tracking](Actions/CognitoWrapper.cs#L248) (`ConfirmDevice`)
* [Get a token to associate an MFA application with a user](Actions/CognitoWrapper.cs#L147) (`AssociateSoftwareToken`)
* [Get information about a user](Actions/CognitoWrapper.cs#L295) (`AdminGetUser`)
* [Confirm a user](Actions/CognitoWrapper.cs#L213) (`ConfirmSignUp`)
* [Confirm an MFA device for tracking](Actions/CognitoWrapper.cs#L241) (`ConfirmDevice`)
* [Get a token to associate an MFA application with a user](Actions/CognitoWrapper.cs#L133) (`AssociateSoftwareToken`)
* [Get information about a user](Actions/CognitoWrapper.cs#L288) (`AdminGetUser`)
* [List the user pools](Actions/CognitoWrapper.cs#L25) (`ListUserPools`)
* [List users](Actions/CognitoWrapper.cs#L46) (`ListUsers`)
* [Resend a confirmation code](Actions/CognitoWrapper.cs#L271) (`ResendConfirmationCode`)
* [Respond to SRP authentication challenges](Actions/CognitoWrapper.cs#L93) (`RespondToAuthChallenge`)
* [Resend a confirmation code](Actions/CognitoWrapper.cs#L264) (`ResendConfirmationCode`)
* [Respond to an authentication challenge](Actions/CognitoWrapper.cs#L72) (`AdminRespondToAuthChallenge`)
* [Sign up a user](Actions/CognitoWrapper.cs#L318) (`SignUp`)
* [Start authentication with a tracked device](Actions/CognitoWrapper.cs#L190) (`InitiateAuth`)
* [Start authentication with administrator credentials](Actions/CognitoWrapper.cs#L170) (`AdminInitiateAuth`)
* [Verify an MFA application with a user](Actions/CognitoWrapper.cs#L125) (`VerifySoftwareToken`)
* [Sign up a user](Actions/CognitoWrapper.cs#L311) (`SignUp`)
* [Start authentication with a tracked device](Actions/CognitoWrapper.cs#L184) (`InitiateAuth`)
* [Start authentication with administrator credentials](Actions/CognitoWrapper.cs#L156) (`AdminInitiateAuth`)
* [Verify an MFA application with a user](Actions/CognitoWrapper.cs#L111) (`VerifySoftwareToken`)

### Scenarios

Code examples that show you how to accomplish a specific task by calling multiple
functions within the same service.

* [Sign up a user with a user pool that requires MFA](Actions/CognitoWrapper.cs)

## Run the examples

### Instructions


For general instructions to run the examples, see the [README](../README.md#building-and-running-the-code-examples) in the `dotnetv3` folder.
For general instructions to run the examples, see the
[README](../README.md#building-and-running-the-code-examples) in the `dotnetv3` folder.

Some projects might include a settings.json file. Before compiling the project,
you can change these values to match your own account and resources. Alternatively, add a settings.local.json file with
your local settings, which will be loaded automatically when the application runs.
you can change these values to match your own account and resources. Alternatively,
add a settings.local.json file with your local settings, which will be loaded automatically
when the application runs.

After the example compiles, you can run it from the command line. To do so, navigate to
the folder that contains the .csproj file and run the following command:

```
dotnet run
```
Alternatively, you can run the example from within your IDE.

Alternatively, you can run the example from within your IDE.

<!--custom.instructions.start-->
<!--custom.instructions.end-->



#### Sign up a user with a user pool that requires MFA

This example shows you how to do the following:
Expand All @@ -89,12 +99,19 @@ This example shows you how to do the following:
* Set up multi-factor authentication by associating an MFA application with the user.
* Sign in by using a password and an MFA code.

<!--custom.scenario_prereqs.cognito-identity-provider_Scenario_SignUpUserWithMfa.start-->
<!--custom.scenario_prereqs.cognito-identity-provider_Scenario_SignUpUserWithMfa.end-->


<!--custom.scenarios.cognito-identity-provider_Scenario_SignUpUserWithMfa.start-->
<!--custom.scenarios.cognito-identity-provider_Scenario_SignUpUserWithMfa.end-->

### Tests

⚠ Running tests might result in charges to your AWS account.


To find instructions for running these tests, see the [README](../README.md#Tests)
To find instructions for running these tests, see the [README](README.md#Tests)
in the `dotnetv3` folder.


Expand Down
44 changes: 26 additions & 18 deletions dotnetv3/Cognito/Scenarios/Cognito_Basics/CognitoBasics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ static async Task Main(string[] args)
.ConfigureServices((_, services) =>
services.AddAWSService<IAmazonCognitoIdentityProvider>()
.AddTransient<CognitoWrapper>()
.AddTransient<UiMethods>()
)
.Build();

Expand All @@ -34,7 +33,10 @@ static async Task Main(string[] args)
.Build();

var cognitoWrapper = host.Services.GetRequiredService<CognitoWrapper>();
var uiMethods = host.Services.GetRequiredService<UiMethods>();

Console.WriteLine(new string('-', 80));
UiMethods.DisplayOverview();
Console.WriteLine(new string('-', 80));

// clientId - The app client Id value that you get from the AWS CDK script.
string clientId = configuration["ClientId"]; // "*** REPLACE WITH CLIENT ID VALUE FROM CDK SCRIPT";
Expand All @@ -44,7 +46,6 @@ static async Task Main(string[] args)
var userName = configuration["UserName"];
var password = configuration["Password"];
var email = configuration["Email"];
var userPoolId = configuration["UserPoolId"];

// If the username wasn't set in the configuration file,
// get it from the user now.
Expand Down Expand Up @@ -90,12 +91,12 @@ static async Task Main(string[] args)
Console.WriteLine($"Adding {userName} to the user pool");
await cognitoWrapper.GetAdminUserAsync(userName, poolId);

uiMethods.DisplayTitle("Get confirmation code");
UiMethods.DisplayTitle("Get confirmation code");
Console.WriteLine($"Conformation code sent to {userName}.");
Console.Write("Would you like to send a new code? (Yes/No) ");
Console.Write("Would you like to send a new code? (Y/N) ");
var answer = Console.ReadLine();

if (answer.ToLower() == "YES")
if (answer.ToLower() == "y")
{
await cognitoWrapper.ResendConfirmationCodeAsync(clientId, userName);
Console.WriteLine("Sending a new confirmation code");
Expand All @@ -106,25 +107,32 @@ static async Task Main(string[] args)

await cognitoWrapper.ConfirmSignupAsync(clientId, code, userName);

uiMethods.DisplayTitle("Checking status");
UiMethods.DisplayTitle("Checking status");
Console.WriteLine($"Rechecking the status of {userName} in the user pool");
await cognitoWrapper.GetAdminUserAsync(userName, poolId);

var authResponse = await cognitoWrapper.InitiateAuthAsync(clientId, userName, password);
var mySession = authResponse.Session;

var newSession = await cognitoWrapper.AssociateSoftwareTokenAsync(mySession);
Console.WriteLine($"Setting up authenticator for {userName} in the user pool");
var setupResponse = await cognitoWrapper.InitiateAuthAsync(clientId, userName, password);

var setupSession = await cognitoWrapper.AssociateSoftwareTokenAsync(setupResponse.Session);
Console.Write("Enter the 6-digit code displayed in Google Authenticator: ");
string myCode = Console.ReadLine();
string setupCode = Console.ReadLine();

var setupResult = await cognitoWrapper.VerifySoftwareTokenAsync(setupSession, setupCode);
Console.WriteLine($"Setup status: {setupResult}");

Console.WriteLine($"Now logging in {userName} in the user pool");
var authSession = await cognitoWrapper.AdminInitiateAuthAsync(clientId, poolId, userName, password);

Console.Write("Enter a new 6-digit code displayed in Google Authenticator: ");
string authCode = Console.ReadLine();

// Verify the TOTP and register for MFA.
await cognitoWrapper.GetAdminUserAsync(newSession, myCode);
Console.Write("Re-enter the 6-digit code displayed in your authenticator");
string mfaCode = Console.ReadLine();
var authResult = await cognitoWrapper.AdminRespondToAuthChallengeAsync(userName, clientId, authCode, authSession, poolId);
Console.WriteLine($"Authenticated and received access token: {authResult.AccessToken}");

var session2 = await cognitoWrapper.AdminInitiateAuthAsync(clientId, userPoolId, userName, password);
await cognitoWrapper.RespondToAuthChallengeAsync(userName, clientId, mfaCode, session2);
Console.WriteLine(new string('-', 80));
Console.WriteLine("Cognito scenario is complete.");
Console.WriteLine(new string('-', 80));
}
}

Expand Down
Loading

0 comments on commit 6a3ab3b

Please sign in to comment.