I have a few simple routes which I wish to restrict via a simple querystring param. If the key is incorrect or not provided, then I wish to throw a NotAuthorizedException.
Please don't suggest I use WebApi or the equiv - I can't just yet in this scenario.
So i'm not sure if I should be implementing an IAuthorizationFilter or implementing an IActionFilter or even something else.
My code logic?
- Check querystring for key.
- Check my RavenDb (repository) for a user with that key/value.
If they fail any of those checks, then throw the NotAuthorizedException.
I'm assuming I would then decorate a my action method with this filter. I'm also assuming i would need to pass in my repository into this action method also?
Any suggestions please?
So i'm not sure if I should be implementing an IAuthorizationFilter or implementing an IActionFilter or even something else.
You should be implementing an IAuthorizationFilter:
public class MyAuthorizeAttribute: FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
var key = filterContext.HttpContext.Request.QueryString["param_name"];
if (!IsValid(key))
{
// Unauthorized!
filterContext.Result = new HttpUnauthorizedResult();
}
}
private bool IsValid(string key)
{
// You know what to do here => go hit your RavenDb
// and perform the necessary checks
throw new NotImplementedException();
}
}
And if you wanted to use dependency injection into your custom action filter you could take a look at the following article in which you could implement a custom filter provider (IFilterProvider). You could have a marked attribute which you may use on controller actions and then have this custom filter provider simply look whether the action is decorated with this marker attribute and apply the custom authorization filter.
For example:
public class MyAuthorizeAttribute: Attribute
{
}
and your authorization filter will only implement the IAuthorizationFilter, it won't be a FilterAttribute:
public class MyAuthorizationFilter: IAuthorizationFilter
{
private readonly ISomeRepository repository;
public class MyAuthorizationFilter(ISomeRepository repository)
{
this.repository = repository;
}
public void OnAuthorization(AuthorizationContext filterContext)
{
var key = filterContext.HttpContext.Request.QueryString["param_name"];
if (!IsValid(key))
{
// Unauthorized!
filterContext.Result = new HttpUnauthorizedResult();
}
}
private bool IsValid(string key)
{
// You know what to do here => go hit your RavenDb
// and perform the necessary checks
throw new NotImplementedException();
}
}
and then you will have the custom filter provider:
public class MyFilterProvider : IFilterProvider
{
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
if (actionDescriptor.GetCustomAttributes(typeof(MyAuthorizeAttribute), true).Any())
{
var filter = DependencyResolver.Current.GetService<MyAuthorizationFilter>();
yield return new Filter(filter, FilterScope.Global);
}
yield break;
}
}
that will be registered in your Application_Start:
FilterProviders.Providers.Add(new MyFilterProvider());
来源:https://stackoverflow.com/questions/16708942/should-i-be-using-an-iauthorizationfilter-if-i-wish-to-create-an-apikey-restrict