我'开始Asp.Net的Web API,这里是我的问题:
我实现一个自定义过滤器的授权检查我的消息头寻找一个API密钥。 在此基础上的API密钥,我找回我的用户,然后我想看看他是否可以访问某些资源。 资源ID我要检查是在HTTP请求的参数。 但是,当我'在AuthorizationFilter方法,动作参数列表是空的。
我怎样才能做到这一点 ?
如果我使用替代授权过滤器的一个ActionFilter,我怎么能肯定,这将是第一个滤波器来执行? 和全球范围内,我怎么能指定过滤器的执行顺序?
最后一个问题,是否有可能增加一些数据“上管”,我可以取回任何过滤器? 就像一个会话存储,但有限的请求?
感谢您的任何回应
参数绑定已经用完,因此你不能(正如你所看到的)使用前的授权属性运行ActionArguments
集合。 相反,你需要使用请求URI查询参数和路由数据的URI参数,如下面所示。
//request at http://localhost/api/foo/id?MyValue=1
public class MyAuthorizationAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
//will not work as parameter binding has not yet run
object value;
actionContext.ActionArguments.TryGetValue("id", out value);
//Will get you the resource id assuming a default route like /api/foo/{id}
var routeData = actionContext.Request.GetRouteData();
var myId = routeData.Values["id"] as string;
//uri is still accessible so use this to get query params
var queryString = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query);
var myQueryParam = queryString["MyValue"];
//and so on
}
}
关于执行顺序 :
有3点不同的方式指定使用的过滤器的执行顺序的FilterScope枚举 ...范围是全球,控制器和动作。 该AuthoriseAttribute
是“全球”,因此它
指定控制器前一个动作。
如果您需要这3米范围内指定的执行顺序,那么你应该阅读这篇博客文章在这里,你将需要实现一个FilterProvider
要添加一些数据管道 :
使用上的要求属性集合此集合可用于请求的持续时间。
protected override bool IsAuthorized(HttpActionContext actionContext)
{
actionContext.Request.Properties.Add("__MYKEY__","MyValue");
//access this later in the controller or other action filters using
var value = actionContext.Request.Properties["__MYKEY__"];
}
另一种方法去的参数是Execute
这些参数的结合。
try
{
var binding = actionContext.ActionDescriptor.ActionBinding;
var parameters = binding.ParameterBindings.OfType<ModelBinderParameterBinding>();
var newBinding = new HttpActionBinding(actionContext.ActionDescriptor, parameters.ToArray());
newBinding.ExecuteBindingAsync(actionContext, new CancellationToken());
var id = actionContext.ActionArguments["id"] as string;
}
catch
{
base.HandleUnauthorizedRequest(actionContext);
}
注意:您需要确保你只在将来自请求URI参数进行筛选,因为我已经注意到,执行对于那些预计将有来自请求主体将不再转嫁到实际的任何参数绑定行动。 即这些参数将是无效的 。
这只是要注意,你可以做到这一点,我推荐使用GetRouteData()/RouteData
,因为它是不太可能扰乱ASP.NET MVC modelbinding的进一步流动。
var routeData = actionContext.ControllerContext.RouteData;
var id = routeData.Values["id"] as string;