使用Unity 2和MVC 3将类注入Authentication属性

本文关键字:注入 Authentication 属性 Unity MVC 使用 | 更新日期: 2023-09-27 18:27:47

我读了很多文章,指出了如何做到这一点,即:

堆栈溢出解决方案

Brad Wilsons优秀教程

这些看起来确实很有效,然而,当我遵循的一些指导方针时

保护ASP.NET MVC 3应用程序

我好像栽了跟头。对我来说,问题是当我将AuthorizationAttribute添加为GlobalFilter时,而不仅仅是装饰控制器/操作。尽管依赖性解析程序似乎被调用并设置了我的Public exposed[Dependency]属性,但当它实际涉及到我覆盖AuthorizeAttribute的OnAuthorization()方法的代码部分时,我的Public[Dependency]属性为null。

当我从全局过滤器中删除它并装饰控制器时,它似乎可以工作。

如果需要更多信息,我可以发布代码。

编辑:为了进一步扩展这一点,这里是我的一些代码:

global.asax.cs

 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {                        
        // If I have this here the my [Dependency] attribute does not keep it's value
        // If I remove it and decorate the controller the [Dependency] attribute keeps it value
        filters.Add(new BasicAuthenticationAttribute());
        filters.Add(new HandleErrorAttribute());
    }
protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
        // injection of services and data contexts
        var container = new UnityContainer();
        // injections for services
        RegisterUnityServices(container);
        // Filter provides to allow injection into attribute filters
        RegisterUnityFilters(container);
    }
    private void RegisterUnityServices(UnityContainer container)
    {
        container.RegisterType<IDataContext, CDAXDataContext>();
        container.RegisterType<IUploadService, UploadService>();
        container.RegisterType<IAuthenticationService, AuthenticationService>();
        // add more services here ...            
        DependencyResolver.SetResolver(new Models.UnityDependencyResolver(container));            
    }
    private void RegisterUnityFilters(UnityContainer container)
    {
        var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
        FilterProviders.Providers.Remove(oldProvider);
        var provider = new UnityFilterAttributeFilterProvider(container);
        FilterProviders.Providers.Add(provider);            
    }

我的Unity课程取自brad wilsons的例子:

    public class UnityDependencyResolver : IDependencyResolver
{
    readonly IUnityContainer _container;
    public UnityDependencyResolver(IUnityContainer container)
    {
        this._container = container;
    }
    public object GetService(Type serviceType)
    {
        try
        {
            return _container.Resolve(serviceType);
        }
        catch
        {
            return null;
        }
    }
    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return _container.ResolveAll(serviceType);
        }
        catch
        {
            return new List<object>();
        }
    }
}

    public class UnityFilterAttributeFilterProvider : FilterAttributeFilterProvider 
{
    private IUnityContainer _container;
    public UnityFilterAttributeFilterProvider(IUnityContainer container)
    {
        _container = container;
    }
    public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        var filters = base.GetFilters(controllerContext, actionDescriptor);
        foreach (var filter in filters)
        {
            _container.BuildUp(filter.Instance);
        }
        return filters;
    }
    protected override IEnumerable<FilterAttribute> GetControllerAttributes(
                ControllerContext controllerContext,
                ActionDescriptor actionDescriptor)
    {
        var attributes = base.GetControllerAttributes(controllerContext,
                                                      actionDescriptor);
        foreach (var attribute in attributes)
        {
            _container.BuildUp(attribute.GetType(), attribute);
        }
        return attributes;
    }
    protected override IEnumerable<FilterAttribute> GetActionAttributes(
                ControllerContext controllerContext,
                ActionDescriptor actionDescriptor)
    {
        var attributes = base.GetActionAttributes(controllerContext,
                                                  actionDescriptor);
        foreach (var attribute in attributes)
        {
            _container.BuildUp(attribute.GetType(), attribute);
        }
        return attributes;
    }
}

以及My BasicAuthenticationAttribute的基础,其中我具有正在设置但在触发OnAuthorization方法时不保持值的[Dependency]属性。

    public class BasicAuthenticationAttribute : AuthorizeAttribute
{
    [Dependency]
    public IAuthenticationService Authentication { get; set; }
    private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
    {
        validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
    }
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
       // code here that uses the Authentication attribute but it's null
    }

使用Unity 2和MVC 3将类注入Authentication属性

我认为您需要调用属性类中的DependencyResolver。。。不确定[Dependency]属性在此处是否有效。。。因此在OnAuthorization方法中调用IAuthenticationService authentication = DependencyResolver.Current.GetService<IAuthenticationService>();