Ho letto una serie di articoli che evidenziano come fare questo, vale a dire:iniettare in attributo di autenticazione con Unity 2 e MVC 3
Brad Wilsons excellent tutorial
Questi non sembrano funziona bene, ma quando seguo alcune delle linee guida da qui
Securing your ASP.NET MVC 3 Application
i sembra venire un raccoglitore. Il problema per me è quando aggiungo il mio AuthorizationAttribute come GlobalFilter piuttosto che decorare semplicemente un controller/azione. Anche se i resolver di dipendenza sembrano essere chiamati e impostano la mia proprietà Public Dependancy quando effettivamente arriva alla parte del codice dove sto sovrascrivendo il metodo OnAuthorization() di AuthorizeAttribute, il mio attributo pubblico [Dependency] è nullo.
Quando lo rimuovo dal filtro globale e decorare un controller sembra funzionare.
Posso inserire il codice se sono necessarie ulteriori informazioni.
EDIT: Per espandere ulteriormente su questo qui è alcuni del mio codice:
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);
}
Le mie lezioni di Unity prese da Brad wilsons esempi:
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>();
}
}
}
E
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;
}
}
E la base di My BasicAuthenticationAttribute dove ho la proprietà [Dipendenza] che viene impostata ma che non mantiene il valore quando viene attivato il metodo 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
}
No non l'ho fatto. Trovo strano che funzioni se decoro il controller ma non funziona se lo metto in global.ascx. Darò il tuo metodo, ma speravo davvero di implementarlo tramite DIP usando Unity. Al momento funziona, ma il metodo spiega che decorare il controller e non includerlo nel file globale. – dreza
Ho trovato lo stesso comportamento, ha funzionato bene nel controller, ma non nell'attributo/filtro ... non è lì, quindi ho dovuto chiamare DependencyResolver. Commento piuttosto interessante da http://stackoverflow.com/users/759701/ethan-cabiac "non si tratta di una registrazione, ma di come vengono istanziati. Essenzialmente, il framework chiama il nuovo Authenticate() che ignora qualsiasi DI-Container "in questa domanda http://stackoverflow.com/questions/6121050/mvc-3-unity-2-inject-dependencies-into-a-filter – w4ik