我有一个带有自定义基于策略的授权的.Net Core Web API(用于检查JWT上的声明和声明值的策略)。
每次用户调用Web API函数时,我都需要记录(到数据库),即使授权失败(特别是在失败时)。
为此,我覆盖了这些方法OnActionExecuting
和OnResultExecuted
(因为我想在一个过滤器上记录每个请求,在其他过滤器中记录请求的结果)。但是,如果授权失败,则两个过滤器都不会被触发。
这是因为授权过滤器先于其他过滤器(如果请求未经授权,则会使管道短路)。
因此,当用户未经授权调用方法时,我无法记录它(我使用Serilog在服务器上写日志文件,并且在授权失败时工作正常,但我想记录它在数据库中就像授权一样好。)
我尝试在授权之前或之后编写一些过滤器,但我无法做到。可能是我没有以正确的方式思考,而且更简单。
我读了这一切,但我还没想到:
Asp.Net Core policy based authorization ends with 401 Unauthorized
How do you create a custom AuthorizeAttribute in ASP.NET Core?
谢谢!
答案 0 :(得分:1)
您是否尝试过以下选项:
使用覆盖订单的全局过滤器,例如:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc(options =>
{
options.Filters.Add(typeof(MyLoggingFilter), -2);
options.Filters.Add(typeof(MyAuthFilter), -1);
});
}
对于基于属性的过滤器,您可以实现IOrderedFilter
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)]
internal sealed class MyAuthorizationAttribute : Attribute, IAuthorizationFilter, IOrderedFilter
{
public int Order => -2;
}
将记录器注入AuthFilter本身
public MyAuthFilter(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<MyAuthFilter>();
}
答案 1 :(得分:1)
听起来你想在.NET管道中更高的记录? 您可以查看DelegatingHandler类而不是过滤器。在auth过滤器之前,这些处理程序在管道中执行得更高。
public class MyLogMessageHandler : DelegatingHandler
{
protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// Do logging with request or HttpContext.Current
}
}
在你的global.asax.cs(或equiv)中,你会注册处理程序:
GlobalConfiguration.Configuration.MessageHandlers.Add(new MyLogMessageHandler());
查看When to use HttpMessageHandler vs ActionFilter?
此外,我们还有一个API日志记录和分析解决方案,如果您在Azure上有Azure扩展,则可能会有所帮助。 https://www.moesif.com/features(完全披露我是首席执行官)