注射类为验证属性使用Unity 2和MVC 3 [英] Injecting class into Authentication attribute using Unity 2 and MVC 3

查看:157
本文介绍了注射类为验证属性使用Unity 2和MVC 3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读了若干指出,如何做到这一点的文章,分别是:

<一个href=\"http://stackoverflow.com/questions/6121050/mvc-3-unity-2-inject-dependencies-into-a-filter\">Stack溢出的解决方案

布拉德·威尔逊优秀教程

这似乎的确工作得很好,但是当我遵循的一些准则从这里

<一个href=\"http://blogs.msdn.com/b/rickandy/archive/2011/05/02/securing-your-asp-net-mvc-3-application.aspx\"相对=nofollow>保护您的ASP.NET MVC 3应用程序

我似乎栽跟头。我的问题是,当我加我AuthorizationAttribute为GlobalFilter而不仅仅是装饰控制器/动作。虽然依赖关系解析器似乎打了个电话,把我的公共曝光[依赖关系]属性时,它实际上涉及到code,其中我重写AuthorizeAttribute的OnAuthorization()方法,我的公开[依赖]部分属性为null

当我从全局过滤器删除它,装饰一个控制器,它似乎工作。

如果需要更多的信息,我可以张贴code。

编辑:
要在此位置进一步扩大是我的一些code的:

的global.asax.cs

 公共静态无效RegisterGlobalFilters(GlobalFilterCollection过滤器)
    {
        //如果我有这个在这里我的[依赖性]属性​​不保持它的价值
        //如果我删除它,装点控制器[依赖]属性保持它的价值
        filters.Add(新BasicAuthenticationAttribute());
        filters.Add(新HandleErrorAttribute());
    }保护无效的Application_Start()
    {
        AreaRegistration.RegisterAllAreas();        RegisterGlobalFilters(GlobalFilters.Filters);
        的RegisterRoutes(RouteTable.Routes);        //服务和数据上下文的注射
        VAR集装箱=​​新UnityContainer();        //注射治疗服务
        RegisterUnityServices(容器);        //过滤器提供了允许注入属性过滤器
        RegisterUnityFilters(容器);    }    私人无效RegisterUnityServices(UnityContainer容器)
    {
        container.RegisterType&LT; IDataContext,CDAXDataContext&GT;();        container.RegisterType&LT; IUploadService,UploadService&GT;();
        container.RegisterType&LT; IAuthenticationService,&的AuthenticationService GT;();        //此处添加更多的服务......
        DependencyResolver.SetResolver(新Models.UnityDependencyResolver(容器));
    }    私人无效RegisterUnityFilters(UnityContainer容器)
    {
        VAR oldProvider = FilterProviders.Providers.Single(F =&GT; f为FilterAttributeFilterProvider);
        FilterProviders.Providers.Remove(oldProvider);        VAR提供商=新UnityFilterAttributeFilterProvider(容器);
        FilterProviders.Providers.Add(供应商);
    }

我的布拉德威尔逊例子采取统一的类:

 公共类UnityDependencyResolver:的IDependencyResolver
{
    只读IUnityContainer _container;    公共UnityDependencyResolver(IUnityContainer容器)
    {
        this._container =容器;
    }    公共对象GetService的(类型的serviceType)
    {
        尝试
        {
            返回_container.Resolve(的serviceType);
        }
        抓住
        {
            返回null;
        }
    }    公共IEnumerable的&LT;对象&gt; GetServices(类型的serviceType)
    {
        尝试
        {
            返回_container.ResolveAll(的serviceType);
        }
        抓住
        {
            返回新的List&LT;对象&gt;();
        }
    }
}

 公共类UnityFilterAttributeFilterProvider:FilterAttributeFilterProvider
{
    私人IUnityContainer _container;    公共UnityFilterAttributeFilterProvider(IUnityContainer容器)
    {
        _container =容器;
    }    公共覆盖的IEnumerable&LT;滤光器&gt; GetFilters(ControllerContext controllerContext,ActionDescriptor actionDescriptor)
    {
        VAR过滤器= base.GetFilters(controllerContext,actionDescriptor);        的foreach(在过滤器变种过滤器)
        {
            _container.BuildUp(filter.Instance);
        }        返回过滤器;
    }    保护覆盖的IEnumerable&LT; FilterAttribute&GT; GetControllerAttributes(
                ControllerContext controllerContext,
                ActionDescriptor actionDescriptor)
    {        VAR属性= base.GetControllerAttributes(controllerContext,
                                                      actionDescriptor);
        的foreach(在属性var属性)
        {
            _container.BuildUp(attribute.GetType(),属性);
        }        返回属性;
    }    保护覆盖的IEnumerable&LT; FilterAttribute&GT; GetActionAttributes(
                ControllerContext controllerContext,
                ActionDescriptor actionDescriptor)
    {        VAR属性= base.GetActionAttributes(controllerContext,
                                                  actionDescriptor);
        的foreach(在属性var属性)
        {
            _container.BuildUp(attribute.GetType(),属性);
        }        返回属性;
    }
}

和我BasicAuthenticationAttribute的基础上,我对将要被设置,但不能维持的价值[依赖]属性时,在 OnAuthorization 方式被激发。

 公共类BasicAuthenticationAttribute:AuthorizeAttribute
{
    [依赖]
    公共IAuthenticationService认证{搞定;组; }    私人无效CacheValidateHandler(HttpContext的背景下,对象数据,参考HttpValidationStatus validationStatus)
    {
        validationStatus = OnCacheAuthorization(新HttpContextWrapper(上下文));
    }    公共覆盖无效OnAuthorization(AuthorizationContext filterContext)
    {
       // code这里使用的身份验证属性,但它为空
    }


解决方案

你拿到这解决了吗?
我认为你需要调用DependencyResolver在属性类......不知道,如果 [依赖] 属性在这里工作......所以在 OnAuthorization 方法调用 IAuthenticationService认证= DependencyResolver.Current.GetService&LT; IAuthenticationService&GT;();

I've read a number of articles that point out how to do this, namely:

Stack overflow solution

Brad Wilsons excellent tutorial

These do appear to work well, however when I follow some of the guidelines from here

Securing your ASP.NET MVC 3 Application

I seem to come a cropper. The issue for me is when I add my AuthorizationAttribute as a GlobalFilter rather than just decorating a controller/action. Although the dependancy resolvers seem to be called and set my Public exposed [Dependancy] property when it actually comes to the part of the code where I am overriding the OnAuthorization() method of AuthorizeAttribute, my public [Dependency] attribute is null.

When I remove it from global filter and decorate a controller it seems to work.

I can post code if more information is required.

EDIT: To further expand on this here is some of my code:

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);            
    }

My Unity classes taken from brad wilsons examples:

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

And

    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;
    }
}

And the basis of My BasicAuthenticationAttribute where I have the [Dependency] property that is being set but not maintaining the value when the OnAuthorization method is fired.

    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
    }

解决方案

Did you get this solved? I think you need to call the DependencyResolver in the attribute class...Not sure if the [Dependency] attribute works here...so in the OnAuthorization method call IAuthenticationService authentication = DependencyResolver.Current.GetService<IAuthenticationService>();

这篇关于注射类为验证属性使用Unity 2和MVC 3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆