.Net core JWT authentication using AWS Cognito User Pool

While working with .net core I needed to create API. For this what I aimed to have was proper authentication. Therefore I decided to use JSON Web Token (JWT) authentication.

However I wanted to avoid creating any of this logic by myself or spending too much time on it. That’s why I decided to use AWS Cognito User Pools to provide me with user management and to generate JWT I need.

It took me some time to gather information how to wire it all together so I will try to outline the most important.

AWS setup

  1. Create user pool in AWS Cognito
  2. Get the newly created user pool ID and run the following command

    * if you want to you can also just navigate to the URL (https://cognito-idp.<region>.amazonaws.com/<user-pool-id>/.well-known/jwks.json ) . Just replace region and user pool ID with correct information.
  3. The information you receive will be used by us to validate the tokens given by AWS.
  4. Save the results for later use.

.Net core API project

  1. Create new .net core webapi project
  2. Install additional packages

  3. add JWT authentication policy ( we will decorate our controllers with it )

  4. Before making further modifications we will add 2 methods used which will be used to validate the signature and issuer ( this has potential to be made much better 🙂 )Key is the “n” value and Expo is the “e” value in the keys you got form the url in AWS setup

  5. Modify Configure method to enable JWT

    The issuer format has the following format : https://cognito-idp.<region>.amazonaws.com/<user-pool-id>


  6. Modify controller and enable the authentication by using the following decorator


Testing the solution

With the authentication enabled we get the following while requesting controller


And if we pass the JWT 🙂




Full gist below 🙂


16 thoughts on “.Net core JWT authentication using AWS Cognito User Pool

  1. You need to dispose RSA object to avoid Memory Leak:

    public RsaSecurityKey SigningKey(string key, string expo)
    using (RSA rsa = RSA.Create())
    new RSAParameters
    Modulus = Base64UrlEncoder.DecodeBytes(key),
    Exponent = Base64UrlEncoder.DecodeBytes(expo)
    return new RsaSecurityKey(rsa);

    1. Thanks Vladimir! That is really good point! I have not looked at optimisation of the code. This one was the “v1” to get things working!

  2. I’ve found that you can simply just use the following in .NET Core 1.1.x

    app.UseJwtBearerAuthentication(new JwtBearerOptions()
    Authority = “https://cognito-idp..amazonaws.com/”,
    Audience = “”

    1. With ASP.NET Core 2.0 …

      .AddJwtBearer(options =>
      options.IncludeErrorDetails = true;
      // ID of the client application (get it from your cognito user pool config); either hardcoded or configureable via IConfiguration if needed
      options.Audience = “876jkgjkhgkjhgkjhg”;
      // URL of Identity Server; use IConfiguration instead of hardcoding
      options.Authority = “https://cognito-idp.us-east-1.amazonaws.com/us-east-1_asdasdasd”;
      // require HTTPS (may be disabled in development, but I advise against it)
      options.RequireHttpsMetadata = false;

      1. im getting this: www-authenticate →Bearer error=”invalid_token”, error_description=”The audience is invalid”.

        Any idea why? also, how do you set up cognito to use it like this?

  3. Thank you for the exellent example! it has worked for me just fine.

    I am trying to work out the other part of the equation – client auth.

    Are you able to share any resources you found that guide you through setting up cognito as client_credentials flow provider?

    The AWS documentation is a bit vague on this one.

    Specifically, this guide http://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html

    mentioning the following:
    Must be a preregistered client in the user pool. The client must be enabled for Amazon Cognito federation.

    how did you manage to enable your client for Amazon Cognito federation?

    Thanks in advance!

Leave a Reply

Your email address will not be published. Required fields are marked *