ASP.NET Core 2.0 OIDC Authentication Using AWS Cognito

AWS Cognito has two parts: User Pools and Federated Identities. With Cognito User Pools, you can add sign-up and sign-in functionality to your ASP.NET Core 2.0 web apps. Although the blog posts such as this one illustrates the use of AWS SDK, you can use Cognito without SDK. Cognito User Pools allow you to integrate your apps using OpenID Connect (OIDC). This will be handy especially when you want to use Cognito with an app such as a third-party product for which you don’t have the source code to tinker with. Of course, the app must support OIDC and that attributes related to OIDC are configurable. Anyways, the objective of this post is to show Cognito integration with ASP.NET Core 2.0 app and that you have the source code, which you can modfiy to your heart’s content.

Create a User Pool and add an app client. Check the “Generate client secret” checkbox so that a client secret gets generated. Also, make sure Cognito User Pool is one of the enabled identity providers. In the “Allowed OAuth Flows”, select “Authorization code grant”. Select any scope you want. Last but not least, make sure you specify a callback URL. For ASP.NET Core app, you can specify http://localhost:5000/signin-oidc. Of course, this is only for testing. That done, Cognito is configured. If you are not familiar with Cognito, you will need to look at AWS documentation to configure correctly to what you need.

Create a new ASP.NET Core 2.0 app and select “Web Application(Model-View-Controller)”. Change the Startup class as follows to enable OIDC authentication.

public void ConfigureServices(IServiceCollection services)

    services.AddAuthentication(options =>
        options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    .AddOpenIdConnect(options =>
        options.ResponseType = "code";
        options.MetadataAddress = "https://cognito-idp.{region}{userPoolId}/.well-known/openid-configuration";
        options.ClientId = "<Client ID from Cognito>";
        options.ClientSecret = "<Client secret from Cognito>";

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

    // Rest of the stuff goes here

    app.UseMvc(routes =>
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");

In the HomeController, apply the [Authorize] tag.

public class HomeController : Controller { }

Finally, modify the Views/Home/Index.cshtml as follows.

    ViewData["Title"] = "Home Page";

<div class="alert alert-success">Hello, @User.Claims.FirstOrDefault(c => c.Type.Equals("cognito:username"))?.Value</div>

<table class="table table-striped table-bordered">

    @foreach (var claim in User.Claims)

Create a user in Cognito User Pools using AWS Console. And, that’s it. If you navigate to http://localhost:5000 (assuming you are using port 5000), you will be redirected to the Cognito page where you can enter the user ID and password. On successful authentication, you get directed to the home page and it should list your claims like this. b1fbaaea-5da3-4d97-a673-b2cf459788a5
email_verified true
token_use id
cognito:username badri

UPDATE – Oct 2018 – There are quite a bit of comments related to getting redirect errors, etc. I’m sorry I couldn’t help. It is mainly about what you have configured with Cognito. On hindsight, I feel I should have provided screen shots. I did not save the Cognito config and for me to do this now, I don’t have that time. Hopefully, I do that sometime in the future.

5 thoughts on “ASP.NET Core 2.0 OIDC Authentication Using AWS Cognito

  1. One piece of missing guidance when setting up the app integration:

    “Another configuration that may be important is the App integration > Domain name. It allows us to configure what will be the domain of the sign-in and sign-up pages.”
    Which is described here:

    Once this domain name is configured, the code from this article will work. Otherwise you will receive an error:

    “The server did not understand the operation that was requested.”

    As described by the stack overflow question here:

  2. I don’t have the solution now. I should have deleted it but this post contains all the source code the solution would have.

  3. Having some trouble getting this to work… can you post a sample solution on github or something?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.