C# Authorization in .NET Core API’s using Attributes, TypeFilterAttribute and IAuthorizationFilter

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:

Advertisement

About briancaos

Developer at Pentia A/S since 2003. Have developed Web Applications using Sitecore Since Sitecore 4.1.
This entry was posted in .net, .NET Core, c#, General .NET and tagged , , , . Bookmark the permalink.

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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.