AWS Mobile Blog

Sign Up and Confirm With Amazon Cognito User Pools Using C#

by Dennis Hills | on | in .NET* | Permalink | Comments |  Share

This post was authored by Tom Moore & Mike Morain, AWS Solutions Architects.

With Amazon Cognito, you can add user sign-up and sign-in to your mobile and web apps. You can also authenticate users through social identity providers such as Facebook, Twitter, or Amazon; with SAML identity solutions; or by using your own identity system.

Amazon Cognito user pools are for mobile and web app developers who want to handle user registration and sign-in directly in their apps. Previously, you needed to implement your own user directory to create user accounts, store user profiles, and implement password recovery flows to support user registration and sign-in.

This post follows on from the Basics – User Registration and Authentication post, and is intended to function as a companion to that post. The basics post walked through the process of setting up an Amazon Cognito user pool that can be accessed through an MVC 5 web site. This post walks through the process of developing a native Windows application to leverage the same app pool, by adding another app to the user pool for native Windows applications.

PREREQUISITES

 

COMPLETE THE WALKTHROUGH IN THE BASICS TUTORIAL

The previous blog post describes the steps to create your Amazon Cognito user pool and to get basic authentication working. You should complete all the steps in that post and ensure that you can successfully create accounts and authenticate to the user pool. This post assumes that you have access to the user pool created in that post, including the user pool ID and the identity pool ID, and that you are able to create a new client ID for the application to use.

VISUAL STUDIO

This blog post assumes that you are using Microsoft Visual Studio 2015 Community Edition. This edition is available for free from Microsoft at https://www.visualstudio.com/vs/community/.

NEW CLIENT ID

Each client that is authenticating to a user pool in Amazon Cognito requires a unique client ID.
To obtain a new client ID:

• Sign in to the AWS Management Console.
• Choose Amazon Cognito.
• Choose Manage your user pools.
• Choose the user pool you created in the previous post.
• In the lower left, choose Apps.
• In the list of applications, choose Add another App.

Give your application a name, select the following options, choose Create App, and then choose Save Changes.

After the application is created, note the client ID to use later.

PROJECT SETUP

Open Visual Studio 2015 and select the new project option.

From the built in templates, choose Classic Desktop application, and choose a project type of WPF Application. This option creates a blank WPF application to use as a starting point for this tutorial. Give the application a name and a location, and then click OK. Visual Studio now sets up the boilerplate code for your initial project.

After the application is created, run the application to ensure that the boilerplate code compiles correctly on your machine.

INSTALLING DEPENDENCIES

The first step to incorporate Amazon Cognito in your application is installing the necessary SDK components. You can use the built-in NuGet functionality to install these components.

Right-click in the Solution Explorer and then choose Manage NuGet Packages.

From the NuGet window, choose Browse, and in the search box type AWSSDK. The AWS SDK for .NET has many components, so you can install only the portions of the SDK that you need for your application. For this blog post we are working with Amazon Cognito to authenticate your application, so you can install only these components for now. In future posts, we will install additional components to access other AWS resources.

Note: All versions of the components used in this blog post are for version 3.x of the AWS SDK for .NET. Version 2 components are available in the NuGet repository for compatibility with older applications; however these should not be used. The following version numbers are correct as of the writing of this blog post.

Select and install the following NuGet packages:
• AWSSDK.Core (v3.3.7.1)
• AWSSDK.CognitoIdentity (v 3.3.1.1)
• AWSSDK.CognitoIdentityProvider (v3.3.2.3)

BUILDING THE INTERFACE

After you install the required components, you can build the Windows user interface for the application to interact with Amazon Cognito. In Visual Studio, add a second WPF window to act as the sign-up page. Right-click the project, choose Add, and then choose New Item. Choose WPF from the category of templates, and choose Windows (WPF) as the template. Name the new page SignUp.xaml and choose Add.

Open the MainWindow.xaml file and replace the default Grid XAML with the following:

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Column="1" Grid.Row="1">
            <TextBlock>User Name:</TextBlock>
            <TextBox Name="UserNameTextBox" />
            <TextBlock>Password:</TextBlock>
            <PasswordBox Name="PasswordTextBox" />
            <Button Name="LoginButton" Click="LoginButton_Click" Content="Login" />
        </StackPanel>
        <Button Name="SignUpButton" Grid.Column="2" Grid.Row="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="SignUpButton_Click" Content="Sign Up" />
    </Grid>

This creates a basic login page with a button to launch a sign-up form. The login code is filled in later. Right-click the file and select View Code.

Open SignUp.xaml and replace the default Grid tag with the following XAML:

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Column="1" Grid.Row="1">
            <TextBlock>User Name:</TextBlock>
            <TextBox Name="UserNameTextBox" />
            <TextBlock>Password:</TextBlock>
            <PasswordBox Name="PasswordTextBox" />
            <TextBlock>Email:</TextBlock>
            <TextBox Name="EmailTextBox" />
            <Button Name="SignUpButton" Click="SignUpButton_Click" Content="Sign Up" />
            <TextBlock>Confirmation Code:</TextBlock>
            <TextBox Name="ConfirmatinTextBox" />
            <Button Name="ConfirmButton" Click="ConfirmButton_Click" Content="Confirm Email" />
        </StackPanel>
    </Grid>

INTEGRATING AMAZON COGNITO

ENABLE APPLICATION CONFIGURATION

Add a reference to the System.Configuration assembly into the project.

Open the App.Config file for the application and add the following code:

  <appSettings>
    <!-- AWS Cognito Identity Settings -->
    <add key="AWSRegion" value="{Your Region}" />
    <add key="CLIENT_ID" value="{Your Cognito Client ID}" />
    <add key="USERPOOL_ID" value="{Your User Pool ID}" />
    <add key="IDENITYPOOL_ID" value="{Your Identity Pool Id}" />
    <add key="IDENITY_PROVIDER" value="{Your Identity Provide}" />
  </appSettings>

Warning: The curly bracket sections must be replaced with the values from the user pool that you set up.

ENABLE NAVIGATION

Right-click MainWindow.xaml and choose View Code. In the code editor, make the following changes to the form code.

Add the following using statements to import the necessary AWS and supporting modules:

using Amazon;
using Amazon.Runtime;
using Amazon.CognitoIdentityProvider;
using Amazon.CognitoIdentityProvider.Model;
using System.Threading.Tasks;
using System.Configuration;

Add the following  items to the class as member variables.

private readonly AmazonCognitoIdentityProviderClient _client = new AmazonCognitoIdentityProviderClient();
private readonly string _clientId = ConfigurationManager.AppSettings["CLIENT_ID"];
private readonly string _poolId = ConfigurationManager.AppSettings["USERPOOL_ID"];

Add the following method to the form to handle opening the registration dialog.

private void SignUpButton_Click(object sender, RoutedEventArgs e)
{
       SignUp signUpDlg = new SignUp(_client);
signUpDlg.ShowDialog();
}

The code provides the ability to launch your sign-up page in the application, which enables you to create new accounts in Amazon Cognito.

IMPLEMENT SIGN-UP

The sign-up page and related code are used to enable a client application to create user accounts within the Amazon Cognito identity provider. This assumes that you want all user accounts to be created from the end-user application. If you do not intend for the application to create users, then you should remove the sign-up page from the application, along with the code to launch the sign-up page.

The process of creating users is performed by Amazon Cognito within your AWS account. All of the rules governing accounts are maintained in the Amazon Cognito user pool configuration. The following code shows basic user creation. You can modify it to suit your business processes; for example, if you require more options for user creation.

Right-click the SignUp.xaml page and choose View Code to edit the sign-up code.

Update the boilerplate code for the SignUp class with the following:

private readonly string _clientId = ConfigurationManager.AppSettings["CLIENT_ID"];
private readonly string _poolId = ConfigurationManager.AppSettings["USERPOOL_ID"];
private AmazonCognitoIdentityProviderClient _client;

public SignUp(AmazonCognitoIdentityProviderClient client)
{
        InitializeComponent();

        _client = client;
}

This enables the application to pass the Amazon Cognito client to the Signup.xaml form, and retrieves the client ID, which is used for the sign-up process.

Add the following code to the SignUp.xaml form.

private async void SignUpButton_Click(object sender, RoutedEventArgs e)
{
     try
     {
         SignUpRequest signUpRequest = new SignUpRequest()
         {
               ClientId = _clientId,
               Password = PasswordTextBox.Password,
               Username = UserNameTextBox.Text
         };
         AttributeType emailAttribute = new AttributeType()
         {
              Name = "email",
              Value = EmailTextBox.Text
         };
         signUpRequest.UserAttributes.Add(emailAttribute);

         var signUpResult = await _client.SignUpAsync(signUpRequest);
     }
     catch (Exception ex)
     {
        string message = ex.Message;
        MessageBox.Show(message, "Sign Up Error");
     }
}

This code implements a handler for the sign-up button. The sign-up button handles the process of Amazon Cognito creating an account from the client. If your user pool requires additional attributes for the user, you include them here along with the email attribute in the preceding example.

After the user is created in Amazon Cognito, a confirmation email is sent to the specified email address, along with a confirmation code. The user uses that confirmation code to complete the sign-up process.

Add the following code to the sign-up form to enable account confirmation and complete the sign up process.

private async void ConfirmButton_Click(object sender, RoutedEventArgs e)
{
     try
     {
          Amazon.CognitoIdentityProvider.Model.ConfirmSignUpRequest confirmRequest = new ConfirmSignUpRequest()
          {
               Username = UserNameTextBox.Text,
               ClientId = _clientId,
               ConfirmationCode = ConfirmationTextBox.Text
          };

          var confirmResult = await _client.ConfirmSignUpAsync(confirmRequest);
     }
     catch (Exception ex)
     {
           string message = ex.Message;
           MessageBox.Show(message, "Sign Up Error");
      }
}

The user receives the confirmation code, types it into the Confirmation text box, and clicks the Confirm button. This completes the registration process.

IMPLEMENT SIGN-IN

The final step is to implement the sign-in process for the mobile application. Right-click the MainWindow.xaml file and choose View Code to edit the code for the main dialog box in the application.

Add the following code to your application:

private async void LoginButton_Click(object sender, RoutedEventArgs e)
{
     bool loggedIn = await CheckPasswordAsync(UserNameTextBox.Text, PasswordTextBox.Password);
}

private async Task<bool> CheckPasswordAsync(string userName, string password)
{
     try
     {
          var authReq = new AdminInitiateAuthRequest()
          {
               UserPoolId = _poolId,
               ClientId = _clientId,
               AuthFlow = AuthFlowType.ADMIN_NO_SRP_AUTH
          };
          authReq.AuthParameters.Add("USERNAME", userName);
          authReq.AuthParameters.Add("PASSWORD", password);

          AdminInitiateAuthResponse authResp = await _client.AdminInitiateAuthAsync(authReq);

          return true;
     }
     catch (Exception ex)
     {
           return false;
     }
}

The preceding code enables the user to sign in with Amazon Cognito.

NEXT STEPS

Completion of this walkthrough enables you to create and authenticate against those accounts within your application. The next steps are to allow the user to interact with other AWS resources within your account. These interactions will be covered in subsequent posts.

WHAT DOES IT COST?

The only service used in this walkthrough is Amazon Cognito. This service is free for the first 50,000 monthly active users. Accessing other AWS resources may incur charges.

CONCLUSIONS

This post extended the previous post by using the user pool you created and enabling a Windows native client to sign up, confirm, and authenticate. After you complete this process, you can extend your application to use other AWS capabilities.

Questions or Comments?

Reach out to us via the AWS Mobile Development Forum.