在 dotnet core 3.0 中使用 [Authorize]-attribute 时修改响应内容

Modify content of response when using [Authorize]-attribute in dotnet core 3.0

我们正在使用 [Microsoft.AspNetCore.Authorization.Authorize] 属性来授权对我们 api 的请求。如果 JWT 在 HTTP-Header 中不存在或无效,则会 returned 出现 401 错误。我们想修改响应 body 以包含更多信息,而不是空的 body。我们已尝试执行以下操作:

 app.Use(async (context, next) =>
 {
     var statusCode = context.Response.StatusCode;
     //write a custom body here       
 });

但是状态代码总是 HTTP.200 这在我看来有点奇怪,因为 Postman 告诉我它是 HTTP.401

万一在我们的 api 中抛出异常,我们实施了一个过滤器,该过滤器实施 IActionFilter 到 return 更详细的错误消息。这就是我们希望在 HTTP.401 情况下要做的事情。我可以添加任何过滤器来实现这一目标吗?

因此您需要在 JWT 之前添加您自己的中间件,调用下一个处理程序,检查结果并添加您的自定义响应。

    app.Use(async (context, next) =>
        {
            await next.Invoke();
            var statusCode = context.Response.StatusCode;
        });
    app.UseAuthentication();

您可以改用 app.UseStatusCodePages()

app.UseStatusCodePages(async context =>
        {
            var httpContext = context.HttpContext;
            var statusCode = context.HttpContext.Response.StatusCode;
            //write a custom body here       
            //for example
            await context.HttpContext.Response.WriteAsync(
                "Status code page, status code: " +
                statusCode);
        });

对于那些对我如何解决它感到好奇的人:

我创建了一个 class 来实现 IAsyncAuthorizationFilter

public class AuthorizationFilter : IAsyncAuthorizationFilter
{
   public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
   {
       if(HasAuthorizationAttribute(context))
       {
          var isAuthorized = //Your authorization code
          if(!isAuthorized)
          {
              context.Result = new ObjectResult(..some object to return in response body..)
              {
                        StatusCode = StatusCodes.Status401Unauthorized
              };
          }
       }
   }

    private bool HasAuthorizationAttribute(AuthorizationFilterContext context)
    {
        var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
        return controllerActionDescriptor.MethodInfo.HasAttribute<ClaimsAuthorizeAttribute>();
    }
}

此过滤器在 Startup.cs 方法 ConfigureServices 中注册如下:

 public void ConfigureServices(IServiceCollection services)
 {
     services.AddMvc().AddMvcOptions(options => 
     {
         options.Filters.Add(typeof(AuthorizationFilter));
     }
 }