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


It’s very rare to build an API in .NET Core, and not use Swagger. After all, it’s the easiest self documenting tool available to developers, and provides a great way to test API’s without using a third party tool such as Postman. Setting up Swagger for general use is not really part of this article series, but we already have a previous article on the subject here : https://dotnetcoretutorials.com/2020/01/31/using-swagger-in-net-core-3/. If you are new to using Swagger, have a read as this piece of the Auth0 article series will cover setting up Swagger to work with Auth0, but not setting up Swagger itself!

With that out of the way, let’s jump right in.

Adding Auth0 Config To Swagger

In our startup.cs file, and inside the ConfigureServices method, we will have something similar to “AddSwaggerGen”. What we need to do is add a SecurityDefinition to Swagger. What this does is define how our API is authenticated, and how Swagger can authorize itself to make API calls. At a high level, it’s telling Swagger that “Hey, you need a token to call this API, here’s how to get one”.

The full code looks like so :

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1",
            new OpenApiInfo
            {
                Title = "API",
                Version = "v1",
                Description = "A REST API",
                TermsOfService = new Uri("https://lmgtfy.com/?q=i+like+pie")
            });

    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.OAuth2,
        Flows = new OpenApiOAuthFlows
        {
            Implicit = new OpenApiOAuthFlow
            {
                Scopes = new Dictionary<string, string>
                {
                    { "openid", "Open Id" }
                },
                AuthorizationUrl = new Uri(Configuration["Authentication:Domain"] + "authorize?audience=" + Configuration["Authentication:Audience"])
            }
        }
    });
});

What we are really adding is that SecurityDefinition. It’s somewhat beyond the scope of this article to really get into the nitty gritty of what each of these properties do, but this is the correct setup for Auth0. Also notice that our AuthorizationUrl is using our previous configuration that we set up to get .NET Core Authentication working.

Now move to the Configure method of your startup.cs. You need to modify your UseSwaggerUI call to look like so :

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "API");
    c.OAuthClientId(Configuration["Authentication:ClientId"]);
});

Again, this is using a configuration variable that we set up earlier. All going well, if you open Swagger now, you should see a button saying Authorize at the top like so :

Clicking this and authenticating will redirect you back to Swagger, upon which you can make API calls that will send your bearer token.

If you get the following error :

Callback URL mismatch. The provided redirect_uri is not in the list of allowed callback URLs

It’s because you need to add your swagger URL (e.x. https://localhost:5001/swagger/oauth2-redirect.html) to the list of Allowed Callback URLs for your Auth0 application.

Now here’s where things diverge. If you are using the Authorize attribute on controllers (e.g. You have [Authorize] on top of every Controller class), then you are good to go. You should be able to tell because for each controller action inside Swagger, there will be a padlock icon indicating that authentication is required.

If you don’t see this padlock icon, it means that either you don’t have the correct Authorize attribute applied *or* you are using my method of applying Authorize globally. If it’s the former, then apply the Authorize attribute. If it’s the latter, continue reading below!

Adding SecurityRequirementsOperationFilter To Swagger

Swagger identifies which methods require authentication by looking for the [Authorize] attribute on controllers. But of course, if you are applying this globally as a convention like we mentioned earlier, this attribute won’t be there. So instead, we have to give Swagger a hand.

Add a class in your API project called “SecurityRequirementsOperationFilter”, and paste the following :

public class SecurityRequirementsOperationFilter : IOperationFilter
{
    /// <summary>
    /// Applies the this filter on swagger documentation generation.
    /// </summary>
    /// <param name="operation"></param>
    /// <param name="context"></param>
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        // then check if there is a method-level 'AllowAnonymous', as this overrides any controller-level 'Authorize'
        var anonControllerScope = context
                .MethodInfo
                .DeclaringType
                .GetCustomAttributes(true)
                .OfType<AllowAnonymousAttribute>();

        var anonMethodScope = context
                .MethodInfo
                .GetCustomAttributes(true)
                .OfType<AllowAnonymousAttribute>();

        // only add authorization specification information if there is at least one 'Authorize' in the chain and NO method-level 'AllowAnonymous'
        if (!anonMethodScope.Any() && !anonControllerScope.Any())
        {
            // add generic message if the controller methods dont already specify the response type
            if (!operation.Responses.ContainsKey("401"))
                operation.Responses.Add("401", new OpenApiResponse { Description = "If Authorization header not present, has no value or no valid jwt bearer token" });

            if (!operation.Responses.ContainsKey("403"))
                operation.Responses.Add("403", new OpenApiResponse { Description = "If user not authorized to perform requested action" });

            var jwtAuthScheme = new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
            };

            operation.Security = new List<OpenApiSecurityRequirement>
            {
                new OpenApiSecurityRequirement
                {
                    [ jwtAuthScheme ] = new List<string>()
                }
            };
        }
    }
}

This looks a bit over the top, but actually it’s just telling Swagger that unless it sees an “AllowAnonymous” attribute on an action or a controller, that we can assume it’s supposed to be authenticated. It’s essentially flipping things on it’s head and saying everything requires authentication unless I say so.

Now back in our ConfigureServices method of our startup.cs, we can go :

services.AddSwaggerGen(c => 
{
    //All the other stuff. 
    c.OperationFilter<SecurityRequirementsOperationFilter>();
});

Which will of course add in our new filter to our swagger docs. This means that now, when we use Swagger, by default, all actions will require a JWT token. Perfect!

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.


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.

I’ve recently had to set up a new project using Auth0 as an “Identity As A Service” provider. Essentially, Auth0 provides an authentication service using an OAuth2 flow, meaning I don’t have to store passwords, worry about passwords resets, or implement my own two factor authentication. Everything about authenticating a user is handled by Auth0, it’s great!

What’s not great is their documentation. I’ve had to use Auth0 (And Azure AD B2C) in a tonne of projects over the years. And every time, I’m reminded that their documentation just plain sucks. At a guess, I think it’s because you only do it once. So if you set up Auth0 for your product, you’re only doing that once and you’ll never have to do it again. So any pains in the documentation you quickly get over. Except if you’re me! Because I work across a whole range of projects on a contract basis, I may do a new Auth0 setup up to 3 – 4 times per year. And every time, it’s painful.

In this series, I’m going to show you how to authenticate your API using Auth0, from setting up your Auth0 tenant all the way to setting up Swagger correctly. It will serve as a great guide if it’s your first time using Auth0, and for those more experienced, it will provide a good run sheet every time you have to set up a new tenant.


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


Creating An Auth0 API

The first thing we need to do is create a new “API” within the Auth0 dashboard. From Auth0, click the APIs menu item, click “Create API” and fill it in similar to the following :

The Name field can be anything, and is purely used within the portal. This might be useful if you have multiple different API’s that will authenticate differently, but for the most part, you can probably name it your product.

The “Identifier” is a little more tricky. It plays a similar role to the above in that it identifies which API is being authenticated for, but… Again, if you have one API it’s not too important. I typically do https://myproductname. It does not have to be a URL at all however, but this is just my preference.

Leave the signing algorithm as is and hit Create!

Copy the Identifier you used into a notepad for safe keeping as we will need it later.

Creating Your Auth0 Application

Next we need to set up our Auth0 Application. An application within the context of Auth0 can be thought of as a “solution”. Within your solution you may have multiple API’s that can be authenticated for, but overall, they are all under the same “Application”.

By default, Auth0 has an application created for you when you open an account. You can rename this to be the name of your product like so :

Also take note of your “Domain” and “ClientId”. We will need these later so copy and paste them out into your notepad file.

Further down, make your “Application Type” set to “Single Page Application”.

On this same settings page for your application, scroll down and find the “Allowed Callback URLs”. This should be set up to allow a call back to your front end (e.g. React, Angular etc). But it should also allow for a Swagger callback. (Confusing, I know). But to put it simply, pop in the URL of your local web application *and* the domain of your API application like so :

Remember to hit “Save Changes” right at the bottom of the page.

Adding Configuration To ASP.NET Core

In our .NET Core solution, open up the appsettings.json file. In there, add a JSON node like so :

"Authentication": {
  "Domain": "https://mydomain.us.auth0.com/",
  "Audience": "https://myproduct",
  "ClientId": "6ASJKHjkhsdf776234"
}

We won’t actually use this configuration anywhere except in our startup method, so for now, don’t worry about creating a C# class to represent this configuration.

Next Steps

So far we’ve set up everything we need on the Auth0 side, and we’ve grabbed all the configuration values and put them into ASP.NET Core. Now, we need to set up everything related to authentication inside our .NET Core App. You can check out the next step in the series here : https://dotnetcoretutorials.com/2021/02/14/using-auth0-with-an-asp-net-core-api-part-2-asp-net-core-authentication/

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.

Raygun is a super easy to use monitoring tool. If you’ve ever used New Relic, it’s not too dissimilar, but focuses a bit more on crash reporting and error logging. They currently have a 14 day trial to sign up, and best of all, they have an awesome Nuget package for integrating your ASP.NET Core app. Super easy!

The Basics

To get up and running will only take a few lines of code!

First install the following Nuget package in your package manager console :

Install-Package Mindscape.Raygun4Net.AspNetCore

Next, go into your appsettings.json and add in a setting called “RaygunSettings” and inside that put “ApiKey”. This should all be at the root level so for example my complete appsettings looks like the following :

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "RaygunSettings": {
    "ApiKey": "GbuxW3gkv&^HFGbntt5VGKg=="
  }
}

After this, head over to your startup.cs. In your ConfigureServices method, add a call to “AddRaygun” and pass in your Configuration object.

public void ConfigureServices(IServiceCollection services)
{
	services.AddRaygun(Configuration);
	services.AddMvc();
}

Then in the Configure method, add in the Raygun middleware. Note that this should be early on in the pipeline (If not the very first thing in your pipeline). Remember that Middleware is run in order! If you place the Raygun middleware after the call to UseMvc for example, you will not log anything should an error be thrown inside the Mvc Middleware. It should end up looking a bit like this :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
	app.UseRaygun();
	app.UseMvc();
}

Next we head over to our controller and just throw a test exception inside an action to see how we get on.

[HttpGet]
public string Get()
{
	throw new Exception("This is a test exception!");
}

When we load this in our browser and head over to the Raygun dashboard, wallah!

Manually Logging Exceptions

Now the above is great when you are just trying to catch any old unhandled exception, but there may be cases where you want to log an exception in code that you have caught and you don’t want to crash your entire application. For that, Raygun allows you to manually log exceptions.

Firstly, to log any exception you can do the following basic line of code anywhere you want :

new RaygunClient("MyAppKey").SendInBackground(e);

So if you are in a pinch and just want to get things going, there we go! Done!

One important thing to note is the “SendInBackground”, this should not be done if your code looks something like this :

try
{
	throw new Exception("This is a test exception!");
}
catch (Exception e)
{
	new RaygunClient("MyAppKey").SendInBackground(e);
	throw;
}

Because the throw will cause the application to crash and possible close threads before the message is sent. For that you can use the Sync version which is just “Send”. On top of that, if you are using the Raygun middleware anyway, then you shouldn’t be rethrowing as you will once again log the exception further down the middleware. In simple terms, this should only be used for “handled” exceptions.

In any case, the fact we are “new-ing” up things makes things a little hard to unit test in our code. So let’s create a nice wrapper for ourselves. First, let’s create a “Settings” object that can hold any configuration we might need for the logger. While this is only going to hold an API key at first, it’s an awesome pattern to use as it allows you to easily add new configuration options further down the line without having to mangle the constructor of our logger.

public interface IRaygunLoggerSettings
{
	string ApiKey { get; }
}

public class RaygunLoggerSettings : IRaygunLoggerSettings
{
	public string ApiKey { get; set; }
}

Next create an interface called “IRaygunLogger”. This will be pretty simple at first and will only need to expose a “LogException” method.

public interface IRaygunLogger
{
	void LogException(Exception e);
}

Now let’s create an implementation of this interface called RaygunLogger. Inside this we will actually new up everything to send the exception to Raygun.

public class RaygunLogger : IRaygunLogger
{
	private readonly IRaygunLoggerSettings _raygunLoggerSettings;

	public RaygunLogger(IRaygunLoggerSettings raygunLoggerSettings)
	{
		_raygunLoggerSettings = raygunLoggerSettings;
	}

	public void LogException(Exception e)
	{
		new RaygunClient(_raygunLoggerSettings.ApiKey).SendInBackground(e);
	}
}

Now the final piece of the puzzle in setting this up is to to register all these classes in our DI container. The RaygunLoggerSettings should be registered as a singleton (As the settings will never change) and we can pull the API key direct from the configuration for this. Our RaygunLogger should be a transient instance. It would look something like this :

services.AddSingleton<IRaygunLoggerSettings>(
	new RaygunLoggerSettings
	{
		ApiKey = Configuration.GetSection("RaygunSettings").GetValue<string>("ApiKey")
	});

services.AddTransient<IRaygunLogger, RaygunLogger>();

Now it’s just about injecting our logger where we need it and logging an exception. Below is a controller that has been setup to log a simple caught exception. Now we can actually run tests through this code testing how we handle exceptions etc. Awesome!

public class ValuesController : Controller
{
	private readonly IRaygunLogger _raygunLogger;

	public ValuesController(IRaygunLogger raygunLogger)
	{
		_raygunLogger = raygunLogger;
	}

	[HttpGet]
	public string Get()
	{
		try
		{
			throw new Exception("This is a caught exception!");
		}
		catch (Exception e)
		{
			_raygunLogger.LogException(e);
		}

		return "All good sir!";
	}
}

And when we give it a whirl?!

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.