I searched a long time for a solution for my problem. I have a custom AuthorizeAttribute that needs a Dependency to a "Service" that has access to a DbContext.
Sadly the Dependency Injection did not work in the custom AuthorizeAttribute and was always null.
I came up with an (for me) acceptable solution. Now I want to know if my solution can cause unforeseen behaviour?
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());
}
}
Is this an acceptable solution? Will I run into nasty problems in the future or is there maybe a better way to use Dependency Injection in a custom AuthorizeAttribute?
I have a custom AuthorizeAttribute that needs a Dependency to a
"Service" that has access to a DbContext. Sadly the Dependency
Injection did not work in the custom AuthorizeAttribute and was always
null.
An implementation of IControllerFactory in the System.Web.Mvc namespace creates instances your Controllers for web requests. The Controller Factory uses System.Web.Mvc.DependencyResolver to resolve dependencies in each controller.
However, ActionFilters/Attributes in the MVC pipeline are not created from the Controller Factory so dependencies are not resolved using System.Web.Mvc.DependencyResolver. This is why your dependency was always null.
Now, System.Web.Mvc.DependencyResolver is public and static so you can access it yourself.
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());
}
}
Assuming your UserServicehas a dependency scope of WebRequest, i.e. its lifetime is One Per web request and tied to the lifetime of HttpContext of a web request this will not construct a new UserService if one has been resolved previously or after if this is the first time UserService has been resolved for the given web request.
In ASP.NET Core you can request services easily as below:
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;
}
}
You can also try this:
ASP.NET Web API and dependencies in request scope
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);
Related
I need to access ClaimsPrincipal within the service layer of a Net Core 6 app.
I could always just builder.Services.AddTransient<IHttpContextAccessor, HttpContextAccessor>(); in the Startup.cs & go my merry way but this is a no-no. Makes it difficult to test and more importantly this is a great example of leaky abstraction.
So, now what I have is the following
public class ClaimsProvider : IClaimsProvider
{
private readonly IHttpContextAccessor _httpContextAccessor;
public ClaimsProvider(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public ClaimsPrincipal? GetClaimsPrincipal()
{
return _httpContextAccessor.HttpContext?.User;
}
}
public interface IClaimsProvider
{
ClaimsPrincipal? GetClaimsPrincipal();
}
Within my Startup.cs AddScoped() that takes an IHttpContextAccessor and return an IClaimsProvider. Then I simply build all services against IClaimsProvider
builder.Services.AddScoped<IClaimsProvider>(provider =>
{
var httpContextAccessor = provider.GetRequiredService<IHttpContextAccessor>();
return new ClaimsProvider(httpContextAccessor);
});
And the usual route for my services where I inject it as a dependency
private readonly IClaimsProvider _claimsProvider;
public SomeService(
IWebHostEnvironment hostingEnvironment,
IMapper mapper, IClaimsProvider claimsProvider, ...)
{
_hostingEnvironment = hostingEnvironment ??
throw new ArgumentNullException(nameof(hostingEnvironment));
_mapper = mapper ??
throw new ArgumentNullException(nameof(mapper));
_claimsProvider = claimsProvider;
}
public void SomeMethod()
{
var u = _claimsProvider.GetClaimsPrincipal();
foreach (var claim in u.Claims)
{
Console.WriteLine($"{claim.Type} : {claim.Value}");
}
}
My question is that is the above approach ok? Potentially, is there any other approach that is better than the one shown above?
To prevent a leaky abstract (the need for an IHttpContextAsccessor in your service), I would recommend using the Adapter Pattern.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddHttpContextAccessor();
services.AddScoped<IClaimsProvider, HttpContextClaimsProvider>();
}
public IClaimsProvider
{
public ClaimsPrinciple ClaimsPrinciple { get; }
}
// Adapter
public HttpContextClaimsProvider : IClaimsProvider
{
public HttpContextClaimsProvider(IHttpContextAccessor httpContext)
{
ClaimsProvider = httpContext?.User?.Principle as ClaimsPrinciple;
}
public ClaimsPrinciple ClaimsPrinciple { get; private set; }
}
public class YourService : IYourService
{
private readonly IClaimsProvider _claimsProvider;
public YourService(IClaimsProvider claimsProvider)
{
_claimsProvider= claimsProvider;
}
}
In our design each controller action receives an FooRequest. This is a POCO object where the properties are filled from the model binder by using corresponding attributes:
public class FooRequest : RequestBase
{
[FromRoute]
public int Id { get; set; }
[FromQuery]
public DateTime? Start { get; set; }
[FromBody]
public SomeComplexObject Configuration { get; set; }
}
Additionally we made a derived class using the suffix WithUser that has a ClaimsPrincipal as additional property:
public class FooRequestWithUser : FooRequest, IRequest<FooResponse>
{
public ClaimsPrincipal User { get; set; }
}
In a next step we made a helper class that provides a helper method that can receive the request instance, a claims principal and a type T:
public class RequestBase
{
public T Of<T>(ClaimsPrincipal user) where T: class, new()
{
// Check if T has base of own type
// Create instance and iterate all props to get value
// from this and and set value in instance.
// Additionally use reflection to set user property.
}
}
When our normal request class is derived from this one, we can call it within our controller and create a model containing the user as an additional property and forward it into our services by using MediatR:
public IActionResult DoFoo(FooRequest request)
{
var requestWithUser = request.Of<FooRequestWithUser>(User);
var result = mediator.Send(requestWithUser);
return Ok(result);
}
By this approach the claims principal is bound to the request consumed by the service and not something it has to additionally receive. Also it makes clear, that this request must be somehow authenticated and the service should check for some potential permissions or similar.
The approach you have described is generally considered a valid way to access the ClaimsPrincipal in the service layer of a .NET Core 6 app, as it abstracts the implementation details of the IHttpContextAccessor, making it easier to test and maintain.
An alternative approach could be to use the built-in dependency injection in ASP.NET Core to directly inject the ClaimsPrincipal into the service, without the need for a separate IClaimsProvider interface.
You can do this by registering the ClaimsPrincipal as a service in the ConfigureServices method of the Startup class.
I have an WebApi application that uses Simple Injector and I'm trying to configure a particular filter with controller attribute (with parameters). I have this configuration working in another project that uses Ninject, but I don't know how to do this on Simple Injector.
public enum UserType {
Director,
Developer,
Leader
}
My controller:
[RequiresAtLeastOneOfUserTypes(UserType.Developer, UserType.Leader)]
public class MyController : Controller
{
...
}
My Attribute:
public sealed class RequiresAtLeastOneOfUserTypesAttribute : Attribute
{
public UserType[] TypesToBeVerified { get; set; }
public RequiresAtLeastOneOfUserTypesAttribute(params UserType[] typesToBeVerified)
{
TypesToBeVerified = typesToBeVerified;
}
}
My Filter:
public class RequiresAtLeastOneOfUserTypesFilter : IActionFilter
{
private readonly IUser _user;
private readonly UserType[] _typesToBeVerified;
protected RequiresAtLeastOneOfUserTypesFilter(IUser user, params UserType[] typesToBeVerified)
{
_user = user;
_typesToBeVerified = typesToBeVerified;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
bool authorized = _user.HasAtLeastOneOfTypes(_typesToBeVerified);
if (!authorized)
{
throw new ForbiddenUserException();
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
// do nothing
}
}
And finally my Ninject configuration:
this.BindFilter<RequiresAtLeastOneOfUserTypesFilter>(FilterScope.Controller, 0)
.WhenControllerHas<RequiresAtLeastOneOfUserTypesAttribute>()
.WithConstructorArgumentFromControllerAttribute<RequiresAtLeastOneOfUserTypesAttribute>(
"typesToBeVerified",
attribute => attribute.typesToBeVerified);
My question is: How can I do this configuration using Simple Injector?
The Simple Injector Web API integration packages don't contain an integration feature for action filters as Ninject's integration package does. But such integration can be built in a few lines of code.
There are a few options here. The first option is to revert to resolving services directly from inside your action filter, as demonstrated inside the documentation. This approach is fine when you have a single filter class, but isn't the cleanest approach, and would force you to make changes to your already created filter attribute.
As a second option you can, therefore, create a action filter proxy class, that is able to forward the call to your real filter class, which can than be resolved by Simple Injector:
public class ActionFilterProxy<T> : IActionFilter
where T : IActionFilter
{
public ActionFilterProxy(Container container) => _container = container;
public void OnActionExecuting(ActionExecutingContext filterContext) =>
_container.GetInstance<T>().OnActionExecuting(filterContext);
public void OnActionExecuted(ActionExecutedContext filterContext) =>
_container.GetInstance<T>().OnActionExecuted(filterContext);
}
Using this proxy, you can make the following configuration:
GlobalConfiguration.Configuration.Filters.Add(
new ActionFilterProxy<RequiresAtLeastOneOfUserTypesFilter>(container));
container.Register<RequiresAtLeastOneOfUserTypesFilter>();
This still forces you to make a change to RequiresAtLeastOneOfUserTypesFilter, because Simple Injector can't provide the attribute's information (the UserType[]) to RequiresAtLeastOneOfUserTypesFilter's constructor. Instead,you can change RequiresAtLeastOneOfUserTypesFilter to the following:
public class RequiresAtLeastOneOfUserTypesFilter : IActionFilter
{
private readonly IUser _user;
public RequiresAtLeastOneOfUserTypesFilter(IUser user) => _user = user;
public void OnActionExecuting(ActionExecutingContext filterContext)
{
// Get the attribute from the controller here
var attribute = filterContext.ActionDescriptor.ControllerDescriptor
.GetCustomAttribute<RequiresAtLeastOneOfUserTypesAttribute>();
bool authorized = _user.HasAtLeastOneOfTypes(attribute.TypesToBeVerified);
if (!authorized)
{
throw new ForbiddenUserException();
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
}
A third option to use is the one referred to in the documentation, which is described in this blog post, which discusses a model where you place your filters behind an application-specific abstraction and allow them to be Auto-Registered. It uses the a similar proxy approach. This method is useful when you have multiple/many filters that need to be applied (where their order of execution is irrelevant).
I am building an ASP.NET Core 2 MVC application. A lot of the time I need to make use of dependencies to validate user input. I want my validation methods to be unit testable, and I want to be able to inject mocked dependencies into them. This is something I have previously done in MVC5 to great success but cannot work out the ASP.NET Core 2 equivalent.
This is how I would do it in MVC5:
// the view model to be validated
public class MyViewModel {
public string Username { get; set; }
}
// the model validator that will have dependencies injected into it
public class MyViewModelValidator : ModelValidator
{
private IUserService users;
private MyViewModel model;
public MyViewModelValidator(ModelMetadata metadata, ControllerContext controllerContext, IUserService users)
: base(metadata, controllerContext)
{
this.users = users;
this.model = base.Metadata.Model as MyViewModel;
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
List<ModelValidationResult> errors = new List<ModelValidationResult>();
if (this.users.CheckExists(this.model.Username))
{
errors.Add(new ModelValidationResult() { MemberName = nameof(MyViewModel.Username), Message = "Username is not available" });
}
return errors;
}
}
// this class works out which validator is required for a given model and
// injects the appropriate dependencies that is resolves using unity in my
// in my case
public class ViewModelValidatorProvider : ModelValidatorProvider
{
private IUnityContainer container;
public ViewModelValidatorProvider() => this.container = DependencyResolver.Current.GetService<IUnityContainer>();
public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
{
if (metadata.ModelType == typeof(MyViewModel))
yield return new MyViewModelValidator(metadata, context, this.container.Resolve<IUserService>());
}
}
// the provider is hooked up in the app start in Global.asax.cs file
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ModelValidatorProviders.Providers.Add(new ViewModelValidatorProvider());
}
}
Now I can just create an instance of the validator with mocked dependencies and away I go! Sadly ASP.NET Core 2 doesn't have the ModelValidator class and everything I have found so far seems to want to inject dependencies via the controller or to resolve them with in an IValidatableObjects Validate() function.
Is it possible to do this in MVC Core?
So following the post #Nkosi left in a comment on the question I started down the right path (I think) and ended up implementing a validation system based on type filters.
To start I have a base validator model that we need to implement in our type filters:
public abstract class BaseViewModelValidator<TModel> : IAsyncActionFilter
where TModel : class
{
public async virtual Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// get the model to validate
if (context.ActionArguments["model"] is TModel model)
await this.ValidateAsync(model, context.ModelState);
else
throw new Exception($"View model of type `{context.ActionArguments["model"].GetType()}` found, type of `{typeof(TModel)}` is required.");
await next();
}
public abstract Task ValidateAsync(TModel model, ModelStateDictionary state);
}
Then, because it is much nicer to use it as a named attribute rather than [TypeFilter(typeof(SomeActionFilter))], I create a TypeFilterAttribute that wraps the implementation of my base validator like this:
public class DemoViewModelValidatorAttribute : TypeFilterAttribute
{
public DemoViewModelValidatorAttribute()
: base(typeof(DemoViewModelValidator))
{
}
internal class DemoViewModelValidator : BaseViewModelValidator<DemoViewModel>
{
private readonly ISomeService service;
// dependencies are injected here (assuming you've registered them in the start up)
public DemoViewModelValidator(ISomeService service) => this.service = service;
public async override Task ValidateAsync(DemoViewModel model, ModelStateDictionary state)
{
if (await this.service.CheckSomethingAsync(model))
state.AddModelError(nameof(model.SomeProperty), $"Whoops!!!");
}
}
}
You can then unit test your DemoViewModelValidator to your hearts content! Hopefully someone finds this useful!
I am trying to implement permission based access control with aspnet core. For dynamically managing user roles and permissions(create_product, delete_product etc.), they are stored in the database. Data Model is like http://i.stack.imgur.com/CHMPE.png
Before aspnet core (in MVC 5) i was using custom AuthorizeAttribute like below to handle the issue:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
private readonly string _permissionName { get; set; }
[Inject]
public IAccessControlService _accessControlService { get; set; }
public CustomAuthorizeAttribute(string permissionName = "")
{
_permissionName = permissionName;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
var user = _accessControlService.GetUser();
if (PermissionName != "" && !user.HasPermission(_permissionName))
{
// set error result
filterContext.HttpContext.Response.StatusCode = 403;
return;
}
filterContext.HttpContext.Items["CUSTOM_USER"] = user;
}
}
Then i was using it in action method like below:
[HttpGet]
[CustomAuthorize(PermissionEnum.PERSON_LIST)]
public ActionResult Index(PersonListQuery query){ }
Additionally, i was using HttpContext.Items["CUSTOM_USER"] in views to show or hide html part:
#if (CurrentUser.HasPermission("<Permission Name>"))
{
}
When i decided to switch aspnet core, all my plan was failed. Because there was no virtual OnAuthorization method in the AuthorizeAttribute. I tried some ways to solve problem. Those are below:
Using new policy based authorization(i think it is not suitable for
my scenerio)
Using custom AuthorizeAttribute and AuthorizationFilter(i read this
post https://stackoverflow.com/a/35863514/5426333 but i couldn’t change it properly)
Using custom middleware(how to get AuthorizeAttribute of current
action?)
Using ActionFilter(is it correct for security purpose?)
I couldn’t decide which way is the best for my scenerio and how to implement it.
First question: Is MVC5 implementation bad practice?
Second question: Do you have any suggest to implement aspnet core?
Based on the comments, here an example on how to use the policy based authorization:
public class PermissionRequirement : IAuthorizationRequirement
{
public PermissionRequirement(PermissionEnum permission)
{
Permission = permission;
}
public PermissionEnum Permission { get; }
}
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
{
private readonly IUserPermissionsRepository permissionRepository;
public PermissionHandler(IUserPermissionsRepository permissionRepository)
{
if(permissionRepository == null)
throw new ArgumentNullException(nameof(permissionRepository));
this.permissionRepository = permissionRepository;
}
protected override void Handle(AuthorizationContext context, PermissionRequirement requirement)
{
if(context.User == null)
{
// no user authorizedd. Alternatively call context.Fail() to ensure a failure
// as another handler for this requirement may succeed
return null;
}
bool hasPermission = permissionRepository.CheckPermissionForUser(context.User, requirement.Permission);
if (hasPermission)
{
context.Succeed(requirement);
}
}
}
And register it in your Startup class:
services.AddAuthorization(options =>
{
UserDbContext context = ...;
foreach(var permission in context.Permissions)
{
// assuming .Permission is enum
options.AddPolicy(permission.Permission.ToString(),
policy => policy.Requirements.Add(new PermissionRequirement(permission.Permission)));
}
});
// Register it as scope, because it uses Repository that probably uses dbcontext
services.AddScope<IAuthorizationHandler, PermissionHandler>();
And finally in the controller
[HttpGet]
[Authorize(Policy = PermissionEnum.PERSON_LIST.ToString())]
public ActionResult Index(PersonListQuery query)
{
...
}
The advantage of this solution is that you can also have multiple handlers for a requirement, i.e. if first one succeed the second handler can determine it's a fail and you can use it with resource based authorization with little extra effort.
The policy based approach is the preferred way to do it by the ASP.NET Core team.
From blowdart:
We don't want you writing custom authorize attributes. If you need to do that we've done something wrong. Instead you should be writing authorization requirements.
I had same requirement and i have done it as below and it works fine for me. I am using .Net Core 2.0 Webapi
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Method
, AllowMultiple = true
, Inherited = true)]
public class CheckAccessAttribute : AuthorizeAttribute, IAuthorizationFilter
{
private string[] _permission;
public CheckAccessAttribute(params string[] permission)
{
_permission = permission;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var user = context.HttpContext.User;
if (!user.Identity.IsAuthenticated)
{
return;
}
IRepository service =
(IRepositoryWrapper)context.HttpContext.RequestServices.GetService(typeof(IRepository));
var success = service.CheckAccess(userName, _permission.ToList());
if (!success)
{
context.Result = JsonFormatter.GetErrorJsonObject(
CommonResource.error_unauthorized,
StatusCodeEnum.Forbidden);
return;
}
return;
}
}
In Controller use it like below
[HttpPost]
[CheckAccess(Permission.CreateGroup)]
public JsonResult POST([FromBody]Group group)
{
// your code api code here.
}
For a solution that doesn't require you to add a policy for each permission see my answer for another question.
It lets you decorate your Controllers and Actions with any custom attributes you wish, and access them in your AuthorizationHandler.
I'musing ASP.NET Web API and I need to have authorization so I've created custom authorization attribute
public class CustomAuthorizationAttribute : AuthorizeAttribute
In order to inject dependency inside constructor I have following :
public CustomAuthorizationAttribute(IAccountBL accountBl)
{
_accountBL = accountBl;
}
In IAccountBL I have method which interacts with database checking if user is authorized to make request.
Inside Member API controller I've register that attribute
[CustomAuthorization]
public class MemberController : ApiController
But I get following error
Project.Account.AccountBL' does not contain a constructor that takes 0 arguments
And if I register it like
[CustomAuthorization(IAccountBL)]
Thank you
Action filters are just attributes. You do not have control over when those attributes are instantiated by the CLR. One possibility is to write a marker attribute:
public class CustomAuthorizationAttribute : Attribute { }
and then the actual action filter:
public class CustomAuthorizationFilter : ActionFilterAttribute
{
private readonly IAccountBL accountBL;
public CustomAuthorizationFilter(IAccountBL accountBL)
{
this.accountBL = accountBL;
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<CustomAuthorizationAttribute>().Any() ||
actionContext.ActionDescriptor.GetCustomAttributes<CustomAuthorizationAttribute>().Any())
{
// here you know that the controller or action is decorated
// with the marker attribute so that you could put your code
}
}
}
and finally register it as a global action filter:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
...
IAccountBL accountBL = ...
config.Filters.Add(new CustomAuthorizationFilter(accountBL));
}
}
and finally you could use the marker attribute:
[CustomAuthorization]
public class MemberController : ApiController
{
...
}
You can get dependency in your filter by using extension method GetDependencyScope for class HttpRequestMessage. It's not a canonical way for dependency injection, but can be used as workaround. A basic example may look like this:
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var dependencyScope = context.Request.GetDependencyScope();
var dependency = dependencyScope.GetService(typeof (MyDependencyType));
//use your dependency here
}
This method may be used with constructor injection to simplify unit testing:
public class MyAuthenticationFilter : Attribute, IAuthenticationFilter
{
private Func<HttpRequestMessage, MyDependencyType> _dependencyFactory;
public MyAuthenticationFilter() :
this(request => (MyDependencyType)request.GetDependencyScope().GetService(typeof(MyDependencyType)))
{
}
public MyAuthenticationFilter(Func<HttpRequestMessage, MyDependencyType> dependencyFactory)
{
_dependencyFactory = dependencyFactory;
}
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var dependencyScope = context.Request.GetDependencyScope();
var dependency = dependencyFactory.Invoke(context.Request);
//use your dependency here
}
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public bool AllowMultiple { get; private set; }
}
If anyone finds similar issue here's how I manage to solve it.
My custom filter inherits IAutofacAuthorizationFilter. Besides this one you can also inherit IAutofacExceptionFilter and IAutofacActionFilter.
And inside my DI container I've register this filter for each controller I want to use like this
builder.Register(c => new CustomAuthorizationAttribute(c.Resolve<IAccountBL>()))
.AsWebApiAuthorizationFilterFor<MemberController>()
.InstancePerApiRequest();
If you registered your service on the application using any container, it's very easy to get the instance of your service from anywhere in the scope. Just follow the below code to get your service.
var myService = DependencyResolver.Current.GetService(typeof(IMyService)) as IMyService;
Please make sure you have included System.Web.Mvc in the file.
Happy coding!!!