So the goal here is to define that a specific API endpoint in my .NET Core API requires an authorization token. It’s not all my endpoints that requires authentication, only those I specify.
To obtain this, I would like to decorate my api method in my controller with an attribute stating that this endpoint requires an authorization token in the request header before you are allowed to call it. Like this:
[HttpGet()]
[AuthTokenRequired]
public async Task<IActionResult> GetProfile()
{
// Here goes my code...
}
The “AuthTokenRequired” is an attribute defined by me by combining a TypeFilterAttribute with an IAuthorizationFilter. This combination allows me to create a custom TypeFilterAttribute attribute while still using dependency injection in the class implmenting the IAuthorizationFilter interface.
But enough talk, let’s code.
THE SAMPLE CODE:
You need to see the code in it’s entirely to understand what’s happening. There are 2 classes here:
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using System.Security.Authentication;
using Users.AuthenticationToken;
namespace MyCode
{
// This is the attribute class. This allows you to
// decorate endpoints in your controllers with a
// [AuthTokenRequired] attribute
public class AuthTokenRequiredAttribute : TypeFilterAttribute
{
public AuthTokenRequiredAttribute() : base(typeof(TokenAuthorizationFilter))
{
}
}
// This is the actual code that runs the authorization. By splitting
// the code into 2 classes, you can inject your dependencies into this class
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
public class TokenAuthorizationFilter : Attribute, IAuthorizationFilter
{
// Sample private variables, yours will look different
private readonly SomeSampleRepository _rep;
private readonly IWebHostEnvironment _environment;
public TokenAuthorizationFilter(SomeSampleRepository rep, IWebHostEnvironment environment)
{
// This is just some sample code. This is added
// to show you that you can now use dependency injection
// in this class.
// In your code you will add the classed needed to
// do the proper authorization for you.
_rep = rep;
_environment = environment;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
// Here you will add your authorization code. This is just an
// example of the possibilities in this method. Do your
// method the way you need it to work.
if (_environment.IsDevelopment())
return;
// You can for example retrieve a request header and check the value
var token = context.HttpContext.Request.Headers["AuthToken"];
if (string.IsNullOrEmpty(token))
throw new AuthenticationException("Unauthorized");
if (token != "my-token")
throw new AuthenticationException("Unauthorized");
}
}
}
So first we define the attribute itself. The class is called AuthTokenRequiredAttribute which will create an [AuthTokenRequired] attribute to be used in the api endpoints in your controller.
The attribute instantiates a new class, TokenAuthorizationFilter, and it is this class that actually does the authorization.
When decorating an API endpoint with the [AuthTokenRequired] attribute, the OnAuthorization method will be called each time before the API endpoint is called.
You must implement your own authorization logic here, I just included some inspiration on how to do it.
My controller class looks like this:
using Microsoft.AspNetCore.Mvc;
namespace MyController
{
[ApiController]
[Route("api/[controller]")]
public class ProfileController : Controller
{
[HttpGet()]
[AuthTokenRequired]
public async Task<IActionResult> GetProfile()
{
try
{
// If the [AuthTokenRequired] fails, this
// code will never be called. A AuthenticationException
// will be thown before this code is reached
// Pseudocode: do some code to get the profile and return it
HttpRequest request = this.Request;
return Ok(profile);
}
catch (Exception ex)
{
return BadRequest();
}
}
}
}
That’s it. You are now an authorization expert. Happy coding.
MORE TO READ:
- TypeFilterAttribute Class from Microsoft
- IAuthorizationFilter Interface from Microsoft
- Dependency Injection in IAuthorizationFilter ASP.Net Core 3 from StackOverflow
- How to use ASP.NET Core MVC built-in Filters from GeeksArray
- .NET Core Api – Catch exceptions using a middleware from briancaos
- .NET Core Catch Model Binding Exceptions from briancaos