Using Auth0 With An ASP.NET Core API – Part 2 – ASP.NET Core Authentication


This post is part of a series on using Auth0 with an ASP.NET Core API, it’s highly recommended you start at part 1, even if you are only looking for something very specific (e.g. you came here from Google). Skipping parts will often lead to frustration as Auth0 is very particular about which settings and configuration pieces you need.

Part 1 – Auth0 Setup
Part 2 – ASP.NET Core Authentication
Part 3 – Swagger Setup


Now that we have our Auth0 tenant all set up, it’s time to actually start authenticating users on our API, and validating their JWT tokens. Let’s go!

Setting Up Auth0 With ASP.NET Core Authentication

The first thing we need to do is install the Microsoft Nuget package that validates JWT tokens for us. So from our Package Manager Console we can run :

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer

Next, head to our startup.cs file, and inside our ConfigureServices method, we will add the following :

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
    options.Authority = Configuration["Authentication:Domain"];
    options.Audience = Configuration["Authentication:Audience"];
});

This sets up our JWT authentication to be validated against Auth0. When I did all of this for the first time I thought “I must be missing something here…”. But really that’s it. Any JWT token is validated against Auth0 using the configuration we set up earlier. Too easy!

Next, in our Configure method, we need two additional calls in our pipeline :

app.UseAuthentication();
app.UseAuthorization();

Ordering is important! The call to Authentication must happen before the call to Authorization. Authentication is the act of “authenticating” who someone is, and essentially storing a validated identity against that request. Authorization is the act of authorizing a user against a resource. If you have not authenticated (e.g. Logged in), then how can you be authorized?

The overall order within this method is important too. You should obviously authenticate before you make a call to a controller etc.

Adding Authorize Attribute

To require your controllers to have a logged in user, we must go and place the “Authorize” attribute on each controller like so :

[Authorize]
public class ContactController : ControllerBase
{
}

However, there are a couple of problems with this :

  • You now have to go back and back-add it to all controllers.
  • What if a new controller is added, and someone forgets to add this attribute.

That last point is I think the most important. What we want to do is reverse the Authorize attribute to be opt-out, not opt-in. By default, everything should be locked down to logged in users. Luckily there is a way for us to do just that.

In your startup.cs, inside your ConfigureServices method, you should have a call to “AddControllers” or similar like so :

services.AddControllers()

However, you can also use this call to add in filters that are applied globally, without you having to add the attribute manually to each controller. To do that with our Authorize attribute, we do the following :

services.AddControllers(options =>
{
    var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();

    options.Filters.Add(new AuthorizeFilter(policy));
})

Now the AuthorizeFilter is added globally for every controller within our solution!

Of course the next question will be, what if you want a controller to opt out? We can just use the AllowAnonymous attribute like so :

[AllowAnonymous]
public class AnonController : ControllerBase
{
}

Testing ASP.NET Core Authentication

At this point, your API is actually all set up to authenticate against JWT tokens. In the next step, we are going to talk about how to wire up Swagger to allow you to generate valid test tokens within the Swagger interface. But if you can’t wait that long, or you don’t use Swagger, then you can actually generate test tokens right from Auth0 itself.

Inside the Auth0 Dashboard, select “APIs” from the left hand menu, open the settings for your API and go to the “Test” tab. There, the second box actually contains a valid JWT token that you can use for testing. It’s generated each time you load this page, so it’s good to go immediately. Feel free to test your API at this point with the JWT token here, and validate that everything is set up correctly.

Next Steps

Theoretically, our API is now secured using Auth0. But in 99% of my projects, I use Swagger to test against my API. For that, I want to be able to generate a valid Auth0 JWT token to use for testing, without having to log into Auth0 or use Fiddler on my front end application to intercept a valid token. The next part in our series will investigate doing exactly that : https://dotnetcoretutorials.com/2021/02/14/using-auth0-with-an-asp-net-core-api-part-3-swagger/

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

2 comments

    1. You mean Auth0 using JWT for end users, and API Key (Machine Key) for machine to machine? I’m… Actually not sure. I actually haven’t done an endpoint that has two authentication types in a long time.

Leave a Reply

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