注射类为验证属性使用Unity 2和MVC 3 [英] Injecting class into Authentication attribute using Unity 2 and 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:
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屋!