Asp.net web api 简单注入器将依赖项注入到自定义全局身份验证筛选器和OWIN中间件OAuthAuthorizationServerProvider中

Asp.net web api 简单注入器将依赖项注入到自定义全局身份验证筛选器和OWIN中间件OAuthAuthorizationServerProvider中,asp.net-web-api,dependency-injection,action-filter,simple-injector,.net-attributes,Asp.net Web Api,Dependency Injection,Action Filter,Simple Injector,.net Attributes,我使用简单的注射器作为我们的Ioc容器;我们有两个问题 我们想要注入到我们的自定义身份验证过滤器中;我们阅读了将属性转换为被动属性的帖子:。但我们无法将自定义身份验证筛选器属性转换为被动 public class BearerAuthentication : Attribute, IAuthenticationFilter { public async Task AuthenticateAsync( HttpAuthenticationContext context, Can

我使用简单的注射器作为我们的Ioc容器;我们有两个问题


  • 我们想要注入到我们的自定义身份验证过滤器中;我们阅读了将属性转换为被动属性的帖子:。但我们无法将自定义身份验证筛选器属性转换为被动

    public class BearerAuthentication : Attribute, IAuthenticationFilter
    {
       public async Task AuthenticateAsync(
           HttpAuthenticationContext context, CancellationToken cancellationToken)
        {
    
        }
       public Task ChallengeAsync(
           HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
        {
    
        }
    }
    
  • 我们希望将依赖注入OWin中间件OAuthAuthorizationServerProvider;我们知道我们可以使用begin execution上下文范围,但我们需要一个优雅的解决方案

    using (Ioc.Container.BeginExecutionContextScope())
    {
    
    }
    
  • 更新

    public interface IAuthenticationFilter<TAttribute> where TAttribute : Attribute
    {
        Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken);
        Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken);
    }
    public  class BearerAuthenticationFilter : Attribute, IAuthenticationFilter<BearerAuthenticationFilter>
    {
        private readonly IAuthenticationBusinessEngine _authenticationBusinessEngine;
        private readonly IHttpContextAccessor _httpContextAccessor;
    
        public BearerAuthenticationFilter(IAuthenticationBusinessEngine authenticationBusinessEngine, IHttpContextAccessor httpContextAccessor)
        {
            _authenticationBusinessEngine = authenticationBusinessEngine;
            _httpContextAccessor = httpContextAccessor;
        }
    
        public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
        {
    
             throw new NotImplementedException();  
    
            }
        }
    
        public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
        {
            throw new NotImplementedException();
        }
    
    }
    public class AuthenticationFilterDispatcher : IAuthenticationFilter
    {
        private readonly Func<Type, IEnumerable> _container;
        public AuthenticationFilterDispatcher(Func<Type, IEnumerable> container)
        {
            _container = container;
        }
    
        public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
        {
            var descriptor = context.ActionContext.ActionDescriptor;
            var attributes = descriptor.ControllerDescriptor.GetCustomAttributes<Attribute>(true)
                .Concat(descriptor.GetCustomAttributes<Attribute>(true));
    
            foreach (var attribute in attributes)
            {
                var filterType = typeof(IAuthenticationFilter<>).MakeGenericType(attribute.GetType());
                var filters = _container.Invoke(filterType);
    
                foreach (dynamic actionFilter in filters)
                {
                    await actionFilter.AuthenticateAsync(context, cancellationToken);
                }
            }
        }
    
        public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
        {
            throw new NotImplementedException();
        }
    
        public bool AllowMultiple
        {
            get
            {
                return true;
            }
        }
    }
    
    公共接口IAAuthenticationFilter,其中TatAttribute:属性
    {
    任务AuthenticationAsync(HttpAuthenticationContext,CancellationToken CancellationToken);
    任务ChallengeAsync(HttpAuthenticationChallengeContext,CancellationToken CancellationToken);
    }
    公共类BeareAuthenticationFilter:属性,IAAuthenticationFilter
    {
    私有只读IAAuthenticationBusinessEngine\u authenticationBusinessEngine;
    专用只读IHttpContextAccessor\u httpContextAccessor;
    公共载体AuthenticationFilter(IAAuthenticationBusinessEngine authenticationBusinessEngine,IHttpContextAccessor httpContextAccessor)
    {
    _authenticationBusinessEngine=authenticationBusinessEngine;
    _httpContextAccessor=httpContextAccessor;
    }
    公共异步任务AuthenticateAsync(HttpAuthenticationContext上下文,CancellationToken CancellationToken)
    {
    抛出新的NotImplementedException();
    }
    }
    公共任务ChallengeAsync(HttpAuthenticationChallengeContext,CancellationToken CancellationToken)
    {
    抛出新的NotImplementedException();
    }
    }
    公共类AuthenticationFilterDispatcher:IAAuthenticationFilter
    {
    私有只读Func_容器;
    公共身份验证筛选器Dispatcher(Func容器)
    {
    _容器=容器;
    }
    公共异步任务AuthenticateAsync(HttpAuthenticationContext上下文,CancellationToken CancellationToken)
    {
    var descriptor=context.ActionContext.ActionDescriptor;
    var attributes=descriptor.ControllerDescriptor.GetCustomAttributes(true)
    .Concat(descriptor.GetCustomAttributes(true));
    foreach(属性中的var属性)
    {
    var filterType=typeof(IAAuthenticationFilter).MakeGenericType(attribute.GetType());
    var filters=\u container.Invoke(filterType);
    foreach(过滤器中的动态actionFilter)
    {
    wait actionFilter.authenticateSync(上下文、取消令牌);
    }
    }
    }
    公共任务ChallengeAsync(HttpAuthenticationChallengeContext,CancellationToken CancellationToken)
    {
    抛出新的NotImplementedException();
    }
    公共布尔允许多个
    {
    得到
    {
    返回true;
    }
    }
    }
    
    使用
    IAAuthenticationFilter
    的等效代码为:

    公共接口IAAuthenticationFilter,其中TatAttribute:属性
    {
    任务AuthenticateTasync(TatAttribute属性,HttpAuthenticationContext上下文);
    }
    公共类AuthenticationFilterDispatcher:IAAuthenticationFilter
    {
    私有只读Func容器;
    公共身份验证筛选器Dispatcher(Func容器){
    this.container=容器;
    }
    公共异步任务AuthenticateAsync(HttpAuthenticationContext,
    取消令牌(令牌){
    var descriptor=context.ActionContext.ActionDescriptor;
    var attributes=descriptor.ControllerDescriptor
    .GetCustomAttributes(true)
    .Concat(descriptor.GetCustomAttributes(true));
    foreach(属性中的var属性){
    类型过滤器Type=typeof(IAAuthenticationFilter)
    .MakeGenericType(attribute.GetType());
    IEnumerable filters=this.container.Invoke(filterType);
    foreach(过滤器中的动态actionFilter){
    wait actionFilter.authenticateSync((动态)属性,上下文);
    }
    }
    }
    公共异步任务ChallengeAsync(HttpAuthenticationChallengeContext,
    取消令牌{}
    public bool AllowMultiple{get{return true;}}
    }
    
    注册程序如下:

    GlobalConfiguration.Configuration.Filters.Add(
    新的AuthenticationFilterDispatcher(container.GetAllInstances));
    //对于简单喷油器2.x:
    container.RegisterManyForOpenGeneric(类型为(IAAuthenticationFilter)),
    容器注册,
    新[]{typeof(IAAuthenticationFilter.Assembly});
    //对于简单喷油器3.x:
    容器.RegisterCollection(类型为(IAAuthenticationFilter),
    新[]{typeof(IAAuthenticationFilter.Assembly});
    
    现在,您可以将属性设置为被动属性,并在
    iaauthenticationfilter
    实现中实现所需的逻辑,而不是将属性设置为主动属性

    您的属性和新组件可能如下所示:

    //注意:此属性不是从特定于Web API的任何内容派生的,
    //仅从属性
    公共类RequiresBeareAuthenticationAttribute:属性
    {
    //如果需要,请在此处放置属性
    }
    公共类BeareAuthenticationFilter
    :iaAuthenticationFilter
    {
    私有只读IAAuthenticationBusinessEngine\u authenticationBusinessEngine;
    专用只读IHttpContextAccessor\u httpContextAccessor;
    公共承载身份验证筛选器(
    IAAuthenticationBusinessEngine authenticationBusinessEngine,
    IHttpContextAccessor(httpContextAccessor)
    {
    _authenticationBusinessEngine=authenticationBusinessEngine;
    _httpContextAccessor=httpContextAccessor;
    }
    公共异步任务AuthenticateAsync(RequiresBeareAuthenticationAttribute,
    HttpAuthenticationContext(上下文)
    {
    //TODO:这里的行为
    }
    }
    
    工作wi的等效代码