在我开始这个问题之前,我用Google搜索并尝试了不同的示例,但我找不到适合我的解决方案..
Bootstrapper.cs
public static class Bootstrapper { public static IUnityContainer Initialise() { var container = BuildUnityContainer(); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); return container; } private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); container.RegisterType<IAccountRepository,AccountRepository>(); container.RegisterType<IAdministrationRepository,AdministrationRepository>(); container.RegisterType<IUploadDirectlyRepository,UploadDirectlyRepository>(); container.RegisterType<IUserRepository,UserRepository>(); container.RegisterType<INewsRepository,NewsRepository>(); container.RegisterType<IContactRepository,ContactRepository>(); // register all your components with the container here // it is NOT necessary to register your controllers // e.g. container.RegisterType<ITestService,TestService>(); RegisterTypes(container); return container; } public static void RegisterTypes(IUnityContainer container) { } }
的Application_Start
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); Bootstrapper.Initialise(); } }
工作实例
public class UserController : Controller { private readonly IUserRepository _userRepository; public UserController(IUserRepository userRepository) { _userRepository = userRepository; } public ActionResult GetUser(int userID) { var user = _userRepository.GetUser(userID) return View(user); } }
我要向您展示的以下代码是我想要在我的操作中使用的filter属性.
我想传入一个字符串数组类型的参数,以便我可以验证是否允许当前用户访问该操作.
在我的应用程序中,有两种类型的用户,帐户所有者和访客.对于帐户所有者而言,所有操作都是完全开放的,但对于访客而言,操作因操作而异.例如,某个操作可能要求您拥有至少三个权限之一(读取,写入和编辑).
过滤:
public class ClaimsAuthorizeAccountAccess : AuthorizeAttribute { private IAccountRepository _accountRepository { get; set; } private String[] _permissions { get; set; } public ClaimsAuthorizeAccountAccess(IAccountRepository accountRepository,params String[] permissions) { _permissions = permissions; _accountRepository = accountRepository; } public override void OnAuthorization(AuthorizationContext filterContext) { if (HttpContext.Current.User.IsInRole("Account Owner")) { base.OnAuthorization(filterContext); } else { ClaimsIdentity claimsIdentity = (ClaimsIdentity)HttpContext.Current.User.Identity; List<AccountLinkPermissionDTO> accountLinkPermissions = new List<AccountLinkPermissionDTO>(); int accountOwnerID = 0; Int32.TryParse(claimsIdentity.Claims.Where(c => c.Type == "AccountOwnerID").Select(c => c.Value).SingleOrDefault(),out accountOwnerID); int guestID = 0; Int32.TryParse(claimsIdentity.Claims.Where(c => c.Type == ClaimTypes.Sid).Select(c => c.Value).SingleOrDefault(),out guestID); //NULL accountLinkPermissions = _accountRepository.GetAccountLinkPermissions(accountOwnerID,guestID); if (accountLinkPermissions != null) { List<string> accountLinkPermissionsToString = accountLinkPermissions.Select(m => m.Permission.Name).ToList(); int hits = accountLinkPermissionsToString.Where(m => _permissions.Contains(m)).Count(); if (hits > 0) { base.OnAuthorization(filterContext); } } else { //Guest doesnt have right permissions filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "action","AccessDenied" },{ "controller","Account" }}); } } } }
如果我使用这个过滤器,它看起来像..
[ClaimsAuthorizeAccountAccess("File read","File write,File edit")] public ActionResult Files() { return View(); }
但是这不起作用,因为过滤器需要两个参数(IRepository和string []).显然,这里也不可能使用构造函数注入.
然后我尝试实现可以在here找到的John Allers解决方案.它看起来很有希望,但它给了我这个错误:
An exception of type
‘Microsoft.Practices.Unity.ResolutionFailedException’ occurred in
Microsoft.Practices.Unity.dll but was not handled in user codeAdditional information: Resolution of the dependency Failed,type =
“Fildela.ClaimsAuthorizeAccountAccess”,name = “(none)”.Exception occurred while: while resolving.
Exception is: InvalidOperationException – The property
_accountRepository on type Fildela.ClaimsAuthorizeAccountAccess is not settable.
At the time of the exception,the container was:
Resolving Fildela.ClaimsAuthorizeAccountAccess,(none)
关于如何解决这个坏男孩的任何建议?
谢谢!
解决方法
public static void Start() { // other codes FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First()); FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container)); }
现在,您可以将[Dependency]属性添加到过滤器的公共属性中.
public class ClaimsAuthorizeAccountAccess : AuthorizeAttribute { [Dependency] public IAccountRepository AccountRepository { get; set; } private String[] _permissions { get; set; } public ClaimsAuthorizeAccountAccess(params String[] permissions) { _permissions = permissions; } }