Внедрение класса в атрибут Authentication с использованием Unity 2 и MVC 3 - PullRequest
6 голосов
/ 13 марта 2012

Я прочитал ряд статей, в которых указано, как это сделать, а именно:

Решение по переполнению стека

Отличное руководство Брэда Уилсона

Похоже, что они работают хорошо, однако, когда я буду следовать некоторым рекомендациям, приведенным здесь

Защита вашего приложения ASP.NET MVC 3

Я, кажется, пришел кроппер.Для меня проблема заключается в том, что я добавляю свой AuthorizationAttribute в качестве GlobalFilter, а не просто украшаю контроллер / действие.Несмотря на то, что средства разрешения зависимостей, кажется, вызываются и устанавливают мое открытое свойство [Dependancy], когда оно фактически касается части кода, где я переопределяю метод OnAuthorization () AuthorizeAttribute, мой публичный атрибут [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 взяты из примеров Брэда Уилсона:

    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, где у меня есть свойство [Dependency], которое устанавливается, но не поддерживает значение при запуске метода 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
    }

1 Ответ

3 голосов
/ 20 апреля 2012

Вы решили это?Я думаю, что вам нужно вызвать DependencyResolver в классе атрибутов ... Не уверен, что здесь работает атрибут [Dependency] ... поэтому при вызове метода OnAuthorization IAuthenticationService authentication = DependencyResolver.Current.GetService<IAuthenticationService>();

...