2017-01-30 32 views
0

我有一个基于自定义基于策略的授权的.NET核心Web API(检查JWT上的声明和声明值的策略)。Web API授权失败时登录数据库[Net.Core]

即使授权失败(特别是失败时),每次用户调用Web API函数时,都需要记录(到数据库)。

为此,我重写了这些方法OnActionExecutingOnResultExecuted(因为我想在一个过滤器上记录每个请求,而在另一个过滤器中记录请求的结果)。但是,如果授权失败,则两个过滤器都不会被触发。

这是因为授权过滤器先于其他过滤器(如果请求未经授权,则将管道短路)。

因此,当用户调用一个没有授权的方法时,我无法记录它(我使用Serilog在服务器上编写日志文件,并且在授权失败时工作正常,但我想将其记录到数据库就像授权很好)。

我尝试在授权之前或之后写入一些过滤器,但我无法做到这一点。可能是我没有以正确的方式思考,而且更简单。

我读这一切,但我没有想出:

谢谢!

回答

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>(); 
} 
+0

我不知道可以更改过滤器顺序,谢谢@Fionn,我会尝试(并注入记录器) – Johna

+0

问题是,我有自己的“AuthFilter”,我添加授权作为服务而不是MVC选项(services.AddAuthorization(options => {options.AddPoliciy(使用JWT声明)})),像[this](https: //docs.microsoft.com/en-us/aspnet/core/security/authorization/claims) – Johna

+0

我并不是很熟悉MVC声明授权,但是您可以尝试在内置处理程序之前插入过滤器或中间件运行, – Fionn

1

听起来像是你想在.NET管道记录高? 你可以看看DelegatingHandler类而不是过滤器。这些处理程序在执行过滤之前在管道中执行得更高。

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上,因为有蔚蓝的扩展。 https://www.moesif.com/features(全面披露我是首席执行官)

+0

前插入它谢谢@Derric,我想试试(我没有使用Azure的) – Johna

+0

再次感谢你,这就是我想要的。我尝试使用DelegatingHanlder(您提供的链接非常有用!),然后我意识到在.Net Core而不是HTTP hanlder中使用[Middleware](https://docs.microsoft.com/en-us/ ASPNET /核心/迁移/ HTTP模块)。所以我创建了一个像[this]这样的中间件(http://blog.elmah.io/error-logging-middleware-in-aspnetcore/),并且我需要测试更多,但它正在工作:) – Johna