在 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));
}
}
我们正在使用 [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));
}
}