C# .Net Core Web API 检查 CustomSignature

C# .Net Core Web API Check CustomSignature

总的来说,我是 API 的新手,让我向您介绍 API 的背景以及我想要它做什么。

我有一个 API 是面向外部的,因此每个传入请求都需要检查来自 header 的签名。字面上我的代码在每个控制器调用中都在检查签名并创建了许多重复的代码。

我的问题是如何减少那些重复的代码?我要用 Custom Attributes, or

下面是一些示例代码:

[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" }
  }
}

以上代码只是为了展示,实际的 Sinature 检查逻辑在每个控制器方法上大约有 20 行代码。

是的,您可以使用动作过滤器来做到这一点。在 documentation

中有描述

将您的检查代码放入 OnActionExecuting 方法。因此,如果签名无效,您可以在操作过滤器中写入 Result

如果您需要特定的结果结构,您可以创建自己的 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");
}

并为您的所有端点注册它(如果需要):

services.AddControllersWithViews(options =>
{
    options.Filters.Add<YourActionFilter>();
});

您可以使用基于令牌的身份验证或过滤方法。供参考

Token based authentication