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中使用依赖注入?

asp.net MVC5 -依赖注入和AuthorizeAttribute

我有一个自定义AuthorizeAttribute,它需要一个对a的依赖可以访问DbContext的"服务"。可悲的是依赖性注入不能在自定义AuthorizeAttribute中工作,并且总是null。

IControllerFactorySystem.Web.Mvc命名空间中的实现为web请求创建实例your Controllers。控制器工厂使用System.Web.Mvc.DependencyResolver来解析每个控制器中的依赖项。

然而,ActionFilters/Attributes在MVC管道不是从控制器工厂创建的,所以依赖关系不解决使用System.Web.Mvc.DependencyResolver。这就是为什么你的依赖项总是null

现在,System.Web.Mvc.DependencyResolverpublicstatic,所以你可以自己访问。

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