0

I am new the API in general, let me give you the background of the API and what I want it to do.

I have a API have that are external facing and so every incoming request are required to check the signature from header. literality my code in every controller call are checking the signature and created many duplicated code.

my question is how can reduces those duplicated code ? do I use Custom Attributes, or AuthorizeAttribute

here are some of the example code:

[Route("[controller]")]
[ApiController]
public class ExampleController : ControllerBase
{
  public async Task<Result> Call_1(Rquest request)
  {
    string signaturel;
    signature = Util.getHeaderSignature(request);

    if(unit.IsSinatureValid(signaturel, someVar1, someVar2))
    {
      (My logic)
    }
    else{ return "InvalidSinaturemessage" }
  }
  public async Task<Result> Call_2(Rquest request)
  {
    string signaturel;
    signature = Util.getHeaderSignature(request);

    if(unit.IsSinatureValid(signaturel, someVar1, someVar2))
    {
      (My logic)
    }
    else{ return "InvalidSinaturemessage" }
  }
}

above code is just for showing, the actual Sinature checking logic is around 20 lines of code on every single controller method.

Samuel
  • 3
  • 1
  • I'd probably go with either [a customer filter attribute](https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-6.0) or [a custom authorization policy](https://learn.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-6.0). – Richard Deeming Feb 10 '22 at 11:02

2 Answers2

0

Yes, you can do that using action filters. It's described in documentation

Put your code for checking into OnActionExecuting method. So, you can write Result in the action filter if the signature isn't valid.

In case you need specific result structure you can create your own ObjectResult:

public class ForbiddenObjectResult : ObjectResult
{
    public string Message { get; private set; }
    public ForbiddenObjectResult(object value, string message)
        : base(value)
    {
        StatusCode = StatusCodes.Status403Forbidden;
        Message = message;
    }
}

...
string signaturel;
signature = Util.getHeaderSignature(context.HttpContext.Request);

if(!unit.IsSinatureValid(signaturel, someVar1, someVar2))
{
    context.Result = new ForbiddenObjectResult(filterContext.ModelState, "InvalidSinaturemessage");
}

And to register it for all your endpoints(if needed):

services.AddControllersWithViews(options =>
{
    options.Filters.Add<YourActionFilter>();
});
Serhii
  • 723
  • 1
  • 4
  • 12
0

You can use token based authentication or filter method. For reference

Token based authentication

Custom Filter

SV_
  • 34
  • 4