asp.net MVC5 -依赖注入和AuthorizeAttribute
本文关键字:注入 AuthorizeAttribute 依赖 net MVC5 asp | 更新日期: 2023-09-27 18:05:12
我寻找了很长时间来解决我的问题。我有一个自定义AuthorizeAttribute,它需要依赖于一个可以访问DbContext的"服务"。遗憾的是,依赖注入在自定义AuthorizeAttribute中不起作用,总是为空。
我想出了一个(对我来说)可以接受的解决方案。现在我想知道我的解决方案是否会导致不可预见的行为?
Global.asax.cs
CustomAuthorizeAttribute.AuthorizeServiceFactory = () => unityContainer.Resolve<AuthorizeService>();
CustomAuthorizeAttribute.cs
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public static Func<AuthorizeService> AuthorizeServiceFactory { get; set; }
public Privilege Privilege { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
return AuthorizeServiceFactory().AuthorizeCore(httpContext, Privilege);
}
}
AuthorizeService.cs
public class AuthorizeService
{
[Dependency]
public UserService UserService { private get; set; }
public bool AuthorizeCore(HttpContextBase httpContext, Privilege privilege)
{
ApplicationUser user = UserService.FindByName(httpContext.User.Identity.Name);
return UserService.UserHasPrivilege(user.Id, privilege.ToString());
}
}
这是一个可以接受的解决方案吗?我是否会在未来遇到严重的问题,或者是否有更好的方法在自定义AuthorizeAttribute中使用依赖注入?
我有一个自定义AuthorizeAttribute,它需要一个对a的依赖可以访问DbContext的"服务"。可悲的是依赖性注入不能在自定义AuthorizeAttribute中工作,并且总是null。
IControllerFactory
在System.Web.Mvc
命名空间中的实现为web请求创建实例your Controllers。控制器工厂使用System.Web.Mvc.DependencyResolver
来解析每个控制器中的依赖项。
然而,ActionFilters/Attributes在MVC管道不是从控制器工厂创建的,所以依赖关系不解决使用System.Web.Mvc.DependencyResolver
。这就是为什么你的依赖项总是null
。
现在,System.Web.Mvc.DependencyResolver
是public
和static
,所以你可以自己访问。
public class AuthorizeService : AuthorizeAttribute
{
private UserService UserService
{
get
{
return DependencyResolver.Current.GetService<UserService>();
}
}
public bool AuthorizeCore(HttpContextBase httpContext, Privilege privilege)
{
ApplicationUser user = UserService.FindByName(httpContext.User.Identity.Name);
return UserService.UserHasPrivilege(user.Id, privilege.ToString());
}
}
假设你的UserService
有一个依赖范围WebRequest,即它的生命周期是一个web请求,并绑定到一个web请求的HttpContext
的生命周期,这将不会构建一个新的UserService
,如果一个已经解决之前或之后,如果这是第一次UserService
已经解决了给定的web请求。
你可以像下面这样轻松地请求服务:
public class CustomAuthAttribute : AuthorizeAttribute, IAuthorizationFilter
{
public async void OnAuthorization(AuthorizationFilterContext context)
{
// var user = context.HttpContext.User;
// if (!user.Identity.IsAuthenticated)
// {
// context.Result = new UnauthorizedResult();
// return;
// }
var userService = context.HttpContext.RequestServices.GetService(typeof(UserService)) as UserService;
}
}
你也可以试试这个:
ASP。. NET Web API和请求范围内的依赖项
public override void OnAuthorization(HttpActionContext filterContext)
{
var requestScope = filterContext.Request.GetDependencyScope();
_userService = requestScope.GetService(typeof(IUserService)) as IUserService;
}
//
// Summary:
// Retrieves the System.Web.Http.Dependencies.IDependencyScope for the given request
// or null if not available.
//
// Parameters:
// request:
// The HTTP request.
//
// Returns:
// The System.Web.Http.Dependencies.IDependencyScope for the given request or null
// if not available.
public static IDependencyScope GetDependencyScope(this HttpRequestMessage request);