AWS Developer Tools Blog

Introducing the ASP.NET Core Identity Provider Preview for Amazon Cognito

Yesterday we announced the general availability of the Amazon CognitoAuthentication Extension Library, which enables .NET Core developers to easily integrate with Amazon Cognito in their application.

We want to further simplify the integration process into ASP.NET Core, so today we’re releasing the developer preview of the custom ASP.NET Core Identity Provider for Amazon Cognito.

Targeting .NET Standard 2.0, the custom ASP.NET Core Identity Provider for Amazon Cognito extends the ASP.NET Core Identity membership system by providing Amazon Cognito as a custom storage provider for ASP.NET Identity. In a few lines of code you can add authentication and authorization that’s based on Amazon Cognito to your ASP.NET Core application.

Getting started

You will need to add the following NuGet dependencies to your ASP.NET Core application:

You can start by adding the following user pool properties to your appsettings.json file:

"AWS": {
    "Region": "<your region id goes here>",
    "UserPoolClientId": "<your user pool client id goes here>",
    "UserPoolClientSecret": "<your user pool client secret goes here>",
    "UserPoolId": "<your user pool id goes here>"
}

Alternatively, instead of relying on a configuration file, you can inject your own instances of IAmazonCognitoIdentityProvider and CognitoUserPool client in your Startup.cs file, or use the newly announced AWS Systems Manager to store your web application parameters:

public void ConfigureServices(IServiceCollection services)
{
    ...
    // Adds your own instance of Amazon Cognito clients 
    // cognitoIdentityProvider and cognitoUserPool are variables 
    // that you would have instantiated yourself
    services.AddSingleton<IAmazonCognitoIdentityProvider>(cognitoIdentityProvider);
    services.AddSingleton<CognitoUserPool>(cognitoUserPool);
    ...
}

To add Amazon Cognito as an Identity provider, remove the existing ApplicationDbContext references (if any) in your Startup.cs file, and then add a call to services.AddCognitoIdentity(); in the ConfigureServices method.

public void ConfigureServices(IServiceCollection services)
{
    // Adds Amazon Cognito as Identity Provider
    services.AddCognitoIdentity();
    ...
}

Finally, if it isn’t already active, enable the support for authentication in ASP.NET Core in your Startup.cs file:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // If not already enabled, you need to enable ASP.NET Core authentication
    app.UseAuthentication();
    ...
} 

Using the CognitoUser class as your web application user class

The ASP.NET Core Identity Provider for Amazon Cognito comes with custom implementations of the ASP.NET Core Identity classes UserManager and SigninManager (CognitoUserManager and CognitoSigninManager). These implementations are designed to support Amazon Cognito use cases, such as:

  • User account management (account registration, account confirmation, user attributes update, account deletion)
  • User password management (password update, password reset)
  • User login and user logout (with or without two-factor authentication)
  • Roles and claims management
  • Authorization

Using Amazon Cognito as an Identity membership system is as simple as using CognitoUserManager and CognitoSigninManager in your existing scaffolded Identity controllers.

Register.cshtml.cs

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    if (ModelState.IsValid)
    {
        // Retrieves a new user with the pool configuration set up
        CognitoUser user = _pool.GetUser(Input.UserName);
        // Sets the required user email
        user.Attributes.Add(CognitoAttributesConstants.Email, Input.Email);
        // Set additional attributes required by the user pool
        user.Attributes.Add("custom:domain", "foo.bar");
        // Registers the user in the pool
        SigninResult result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");
            
            await _signInManager.SignInAsync(user, isPersistent: false);
            // Redirects to the account confirmation page
            return RedirectToPage("./ConfirmAccount");
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

You can find complete samples in the Amazon Cognito ASP.NET Core Identity Provider GitHub repository, including user registration, user login with and without two-factor authentication, and account confirmation.

Authentication and authorization

By default, authentication is supported by the Amazon CognitoAuthentication Extension Library using the Secure Remote Password protocol. In addition, ASP.NET Core authorization provides a simple, declarative role and a rich policy-based model to handle authorization.

We use Amazon Cognito groups to support role-based authorization. Restricting access to only users who are part of an “Admin” group is as simple as adding the following attribute to the controllers or methods you want to restrict access to:

[Authorize(Roles = "Admin")]
public class AdminController : Controller
{
}

Similarly, we use Amazon Cognito users attributes to support claim-based authorization. Amazon Cognito prefixes custom attributes with the key “custom:”.

The following snippets shows how you could restrict access to resources to Amazon Cognito users with a specific “domain” attribute value by creating a custom policy and applying it to your resources. You can do this in the ConfigureServices method of your Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
    List<string> authorizedDomains = new List<string>()
    {
        "amazon.com",
        "foo.bar"
    };

    services.AddAuthorization(options =>
    {
        options.AddPolicy("AuthorizedDomainsOnly", policy => policy.RequireClaim("custom:domain", authorizedDomains));
    });
    
    ...
}
[Authorize(Policy = "AuthorizedDomainsOnly")]
public class RestrictedController : Controller
{
}

Providing feedback

This library is in developer preview and we would love to know how you’re using the ASP.NET Core Identity Provider for Amazon Cognito. Please give us any feedback and check out the source on GitHub!

Come join the AWS SDK for .NET community chat on Gitter.
Submit a feature request or up-vote existing ones on the GitHub Issues page.