2012-03-13 24 views
6

Tôi đã đọc một số điều mà chỉ ra làm thế nào để làm được điều này, đó là:tiêm chích lớp thành xác thực thuộc tính sử dụng Unity 2 và MVC 3

Stack overflow solution

Brad Wilsons excellent tutorial

Những điều này dường như hoạt động tốt, tuy nhiên khi tôi thực hiện theo một số nguyên tắc từ đây

Securing your ASP.NET MVC 3 Application

I dường như đến một cropper. Vấn đề đối với tôi là khi tôi thêm AuthorizationAttribute của tôi làm GlobalFilter thay vì chỉ trang trí một controller/action. Mặc dù các giải quyết sự phụ thuộc dường như được gọi và thiết lập thuộc tính [Dependancy] được công khai của tôi khi nó thực sự đến một phần của mã mà tôi đang ghi đè phương thức OnAuthorization() của AuthorizeAttribute, thuộc tính public [Dependency] của tôi là null.

Khi tôi xóa bộ lọc khỏi bộ lọc chung và trang trí bộ điều khiển có vẻ như hoạt động.

Tôi có thể đăng mã nếu cần thêm thông tin.

EDIT: Tiếp tục mở rộng trên đây đây là một số mã của tôi:

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 lớp của tôi lấy từ brad Wilsons ví dụ:

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

Và cơ sở của My BasicAuthenticationAttribute nơi tôi có thuộc tính [Dependency] đang được đặt nhưng không duy trì giá trị khi phương thức OnAuthorization được kích hoạt.

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 
    } 

Trả lời

3

Bạn đã nhận được giải pháp này chưa? Tôi nghĩ rằng bạn cần phải gọi DependencyResolver trong lớp thuộc tính ... Không chắc chắn nếu thuộc tính [Dependency] hoạt động ở đây ... vì vậy trong phương thức OnAuthorization gọi IAuthenticationService authentication = DependencyResolver.Current.GetService<IAuthenticationService>();

+0

Không. Tôi tìm thấy nó lạ rằng nó hoạt động nếu tôi trang trí bộ điều khiển nhưng không hoạt động nếu tôi đặt nó trong global.ascx. Tôi sẽ cung cấp cho phương pháp của bạn một đi nhưng tôi đã thực sự hy vọng để thực hiện nó thông qua DIP sử dụng Unity. Tại thời điểm này nó làm việc nhưng phương pháp giải thích trong đó tôi trang trí bộ điều khiển và không bao gồm nó trong tập tin toàn cầu. – dreza

+0

Tôi tìm thấy cùng một hành vi, làm việc tốt trong bộ điều khiển, nhưng không phải trong thuộc tính/bộ lọc ... nó chỉ là không có, vì vậy tôi cần phải gọi DependencyResolver. Khá thú vị bình luận từ http://stackoverflow.com/users/759701/ethan-cabiac "nó không phải là về việc liệu họ đã được đăng ký, nó là về cách họ được instantiated. Về cơ bản, khuôn khổ được gọi mới Authenticate() mà bỏ qua bất kỳ DI-Container "trong câu hỏi này http://stackoverflow.com/questions/6121050/mvc-3-unity-2-inject-dependencies-into-a-filter – w4ik

Các vấn đề liên quan