如果我希望使用ASP.NET MVC4创建ApiKey受限资源,我应该使用IAuthorizationFilter吗?
我有一些简单的路由,我希望通过一个简单的查询字符串参数进行限制。 如果密钥不正确或未提供,那么我希望抛出NotAuthorizedException
。
请不要建议我使用WebApi或等效 – 我不能在这种情况下使用。
所以我不确定我是应该实现IAuthorizationFilter
还是实现IActionFilter
甚至是其他东西。
我的代码逻辑?
- 检查查询字符串是否有关键。
- 检查我的RavenDb(存储库)以查找具有该键/值的用户。
如果它们未通过任何这些检查,则抛出NotAuthorizedException
。
我假设我会用这个filter装饰我的动作方法。 我还假设我需要将我的存储库传递给这个动作方法吗?
有什么建议吗?
所以我不确定我是应该实现IAuthorizationFilter还是实现IActionFilter甚至是其他东西。
您应该实现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(); } }
如果您想在自定义操作filter中使用依赖项注入,可以查看following article
,您可以在其中实现自定义filter提供程序( IFilterProvider
)。 您可以在控制器操作上使用标记属性,然后让此自定义filter提供程序只查看操作是否使用此标记属性进行修饰并应用自定义授权filter。
例如:
public class MyAuthorizeAttribute: Attribute { }
并且您的授权filter只会实现IAuthorizationFilter
,它不会是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(); } }
然后你将拥有自定义filter提供程序:
public class MyFilterProvider : IFilterProvider { public IEnumerable GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { if (actionDescriptor.GetCustomAttributes(typeof(MyAuthorizeAttribute), true).Any()) { var filter = DependencyResolver.Current.GetService(); yield return new Filter(filter, FilterScope.Global); } yield break; } }
将在您的Application_Start
注册:
FilterProviders.Providers.Add(new MyFilterProvider());