Czytałem wiele artykułów, które wskazują, w jaki sposób to zrobić, a mianowicie:wstrzykiwanie atrybutu uwierzytelniania przy użyciu Jedności 2 i MVC 3
Brad Wilsons excellent tutorial
Te wydają się działa dobrze, jednak kiedy śledzę niektóre z wytycznymi stąd
Securing your ASP.NET MVC 3 Application
I wydaje się, że przybył. Problem dotyczy mnie, gdy dodam moją AuthorizationAttribute jako GlobalFilter, a nie tylko dekorację kontrolera/akcji. Chociaż wywołania zależne wydają się być wywoływane i ustawiają moją publiczną właściwość [Dependancy], kiedy faktycznie dochodzi do części kodu, w której zastępuję metodę OnAuthorization() AuthorizeAttribute, mój publiczny atrybut [Dependency] ma wartość null.
Po usunięciu go z filtru globalnego i dekoracji kontrolera wydaje się działać.
Potrafię pisać kod, jeśli potrzeba więcej informacji.
EDIT: do dalszego rozwoju w tej sprawie Oto mój kodu:
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);
}
moich klas Unity podjęte od Brada Wilsons Przykłady:
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>();
}
}
}
i
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;
}
}
Podstawy metody My BasicAuthenticationAttribute, w której mam ustawioną właściwość [Dependency], ale nie utrzymuję tej wartości po uruchomieniu metody OnAuthorization.
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
}
nie zrobiłem. To dziwne, że działa, gdy dekoruję kontroler, ale nie działa, jeśli umieściłem go w pliku global.ascx. Podam twoją metodę, ale naprawdę chciałem ją zaimplementować poprzez DIP używając Unity. W tej chwili działa, ale metoda wyjaśniona w tym, że dekoruję kontroler i nie włączam go do pliku globalnego. – dreza
Znalazłem to samo zachowanie, działało dobrze w kontrolerze, ale nie w atrybucie/filtrze ... po prostu go tam nie było, więc musiałem zadzwonić do DependencyResolver. Bardzo ciekawy komentarz od http://stackoverflow.com/users/759701/ethan-cabiac "nie chodzi o to, czy są one zarejestrowane, chodzi o to, w jaki sposób są tworzone." Zasadniczo, framework nazywa nowy Authenticate(), który omija każdą DI-Container "w tym pytaniu http://stackoverflow.com/questions/6121050/mvc-3-unity-2-inject-dependencies-into-a-filter – w4ik