如何在ASP.NET Core中使用IAsyncAuthorizationFilter获得依赖注入

问题描述:

我已经实现了IAsyncAuthorizationFilter接口到类;此外,该类来源于Attribute,所以我可以使用它标记控制器类和操作方法。这到目前为止,在操作方法之前调用Task OnAuthorizationAsync(AuthorizationFilterContext context)方法,如果请求未通过身份验证,则返回HTTP 401作为响应。如何在ASP.NET Core中使用IAsyncAuthorizationFilter获得依赖注入

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 
public sealed class CustomAuthenticationAttribute : Attribute, IAsyncAuthorizationFilter 
{ 
    public async Task OnAuthorizationAsync(AuthorizationFilterContext context) 
    { 
     ... 
    } 
} 

这个属性是用来如下...

[CustomAuthenticationAttribute] 
public class SomeDataController : Controller 
{ 
    [HttpGet] 
    public async Task GetData() 
    { 
     ... 
    } 
} 

现在,我想使用的应用程序服务(从数据库获取需要认证的专用密钥信息),并试图用财产注入的。通过ctor注入依赖关系并不是一个好的选择,因为它是作为属性实现的。所以我试图...

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 
public sealed class CustomAuthenticationAttribute : Attribute, IAsyncAuthorizationFilter 
{ 
    public IPrivateKeyLookupService KeyService { get; set; } 

    public async Task OnAuthorizationAsync(AuthorizationFilterContext context) 
    { 
     string publicKey = ... 
     ... 
     var privateKey = await this.KeyService.GetPrivateKeyFrom(publicKey); 
     ... 
    } 
} 

...但属性注入似乎并没有在这里工作。该服务已向IoC注册,但属性未连线。这是一个ASP.NET Core 1.1项目,我使用Autofac。在Startup类我ConfigureServices方法有类似的东西...

public void ConfigureServices(IServicesCollection collection) 
{ 
    ... 

    var containerBuilder = new ContainerBuilder(); 
    containerBuilder.RegisterType<AuthKeyService>().As<IPrivateKeyLookupService>(); 

    containerBuilder.Populate(services); 

    this.container = containerBuilder.Build(); 
} 

确实为IAsyncAuthorizationFilter类型Autofac支持自动布线?如果没有,我怎么能够填充这个功能?

+0

你试过用'[TypeFilter(typeof(CustomAuthenticationAttribute))]'在控制器上注册你的过滤器吗?你可以在这里获得更多信息:https://joonasw.net/view/aspnet-core-di-deep-dive – juunas

+0

@juunas谢谢;几分钟前刚刚找到解决方案。这是典型的...我正在寻找几个小时,然后在我问这个问题时弹出了解决方案( - ;)。 – Matze

它原来是非常简单的...

ASP.NET Core存在TypeFilter属性,这也是一个创建另外一个过滤器(Type指定)和涉及依赖注入满足它的构造函数参数的过滤器。

我改变了执行IAsyncAuthorizationFilter;除去性能并增加了一个构造函数来代替,因为TypeFilter男星注入将现在的工作......

public sealed class CustomAuthenticationAttribute : IAsyncAuthorizationFilter 
{ 
    private readonly IPrivateKeyLookupService keyService; 
    public CustomAuthenticationAttribute(
     IPrivateKeyLookupService keyService) 
    { 
     this.keyService = keyService; 
    } 

    public async Task OnAuthorizationAsync(AuthorizationFilterContext context) 
    { 
     ... 
    } 
} 

因为it's没有必要了,因为还有AttributeUsage属性的声明,我也是从Attribute删除继承。

所以,我可以用我的属性如下...

[TypeFilter(typeof(CustomAuthenticationAttribute))] 
public class SomeDataController : Controller 
{ 
    [HttpGet] 
    public async Task GetData() 
    { 
     ... 
    } 
} 

传递额外的参数的构造函数filter's也可以通过TypeFilter类的object[] Arguments财产。