.net 在自定义授权 MVC4 Web Api 中访问 post 或 get 参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12817202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accessing post or get parameters in custom authorization MVC4 Web Api
提问by olif
Is it possible to access post or get parameters via the HttpActionContext object?
是否可以通过 HttpActionContext 对象访问 post 或 get 参数?
I have a set of sensors that loggs data to a web server that provides a REST api. I would like to introduce some sort of authentication/authorization by letting the sensors include their hardware id in the data and then make a lookup in a database to see if the id exists or not. Since the API provides many web api action methods I would ideally like to use a custom authorization attribute
我有一组传感器,可以将数据记录到提供 REST api 的 Web 服务器。我想通过让传感器在数据中包含它们的硬件 ID 然后在数据库中查找该 ID 是否存在来引入某种身份验证/授权。由于 API 提供了许多 web api 操作方法,我最好使用自定义授权属性
public class ApiAuthorizationFilter : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
return false;
}
}
How can I access the post/get data from the actionContext?
如何从 actionContext 访问 post/get 数据?
EDIT: Example of POST
编辑:POST 示例
POST /Api/api/ActionMethod/ HTTP/1.1\r\n
Content-Type: application/json\r\n
Host: localhost\r\n
Accept: */*\r\n
Content-Length:52\r\n
\r\n
{"Id": '121a222bc', "Time": '2012-02-02 12:00:00'}\r\n
Have a nice day!
祝你今天过得愉快!
回答by Mark Jones
Due to its nature the AuthoriseAttribute looks like it is called in the pipeline before the model binders and parameter bindings have run. You also run into issues when you access the Request.Content and read from it... this can only be done onceand if you are going to try it in your auth attribute you may break the mediaTypeFormater...
由于其性质,AuthoriseAttribute 看起来像是在模型绑定器和参数绑定运行之前在管道中调用。当您访问 Request.Content 并从中读取时,您也会遇到问题...这只能完成一次,如果您要在 auth 属性中尝试它,您可能会破坏 mediaTypeFormater...
in WebAPI, the request body (an HttpContent) may be a read-only, infinite, non-buffered, non-rewindable stream.
在 WebAPI 中,请求主体(一个 HttpContent)可能是只读的、无限的、非缓冲的、不可回绕的流。
UpdateThere are different ways of specifying the execution context... http://msdn.microsoft.com/en-us/library/system.web.http.filters.filterscope(v=vs.108).aspx. The AuthoriseAttribute is "Global" and therefore it is hit too early to access the action information.
更新有多种指定执行上下文的方法... http://msdn.microsoft.com/en-us/library/system.web.http.filters.filterscope(v=vs.108).aspx。AuthoriseAttribute 是“全局”,因此访问操作信息为时过早。
Given you want access to the model and parameters you can change your approach slightly and use an OnActionExecuting filter ("Action" filter scope) instead and throw a 401 or 403 based on your validation.
鉴于您想要访问模型和参数,您可以稍微更改您的方法并使用 OnActionExecuting 过滤器(“Action”过滤器范围),并根据您的验证抛出 401 或 403。
This filter is called later in the execution process and you therefore have full access to the bound data.
此过滤器稍后会在执行过程中调用,因此您可以完全访问绑定数据。
Very simple example below:
下面非常简单的例子:
public class ApiAuthorizationFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
Foo model = (Foo)actionContext.ActionArguments["model"];
string param1 = (string)actionContext.ActionArguments["param1"];
int param2 = (int)actionContext.ActionArguments["param2"];
if (model.Id != "1")
throw new HttpResponseException(System.Net.HttpStatusCode.Forbidden);
base.OnActionExecuting(actionContext);
}
}
Example controller:
示例控制器:
public class Foo
{
public string Id { get; set; }
public DateTime Time { get; set; }
}
public class FoosController : ApiController
{
// PUT api/foos/5
[ApiAuthorizationFilter]
public Foo Put(int id, Foo model, [FromUri]string param1 = null, int? param2 = null)
{
return model;
}
}
What the other answers were saying.... they are right you can, if you can access all you need on the URL, get at stuff via the request; however, I think the model and the request content should be left alone:
其他答案在说什么......他们是对的,如果您可以在 URL 上访问您需要的所有内容,请通过请求获取内容;但是,我认为模型和请求内容应该单独保留:
var queryStringCollection = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query);
//example for param1
string param1 = queryStringCollection["param1"];
//example for param2
int param2 = int.Parse(queryStringCollection["param2"]);
//Example of getting the ID from the URL
var id = actionContext.Request.RequestUri.Segments.LastOrDefault();
回答by simbolo
I accessed the context route data to get the parameters from within a custom AuthorizeAttribute when calling something like /api/client/123/users:
在调用以下内容时,我访问了上下文路由数据以从自定义 AuthorizeAttribute 中获取参数/api/client/123/users:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var clientId = Convert.ToInt32(actionContext.ControllerContext.RouteData.Values["clientid"]);
// Check if user can access the client account.
}
}
回答by jmberon
You can access query string values from your custom authorize attribute by using the following code:
您可以使用以下代码从自定义授权属性访问查询字符串值:
public class ApiAuthorizationFilter : AuthorizeAttribute
{
protected override void OnAuthorization(AuthorizationContext filterContext)
{
var querystring = filterContext.RequestContext.HttpContext.Request.QueryString;
// Do what you need
}
}
回答by vohrahul
Although this question has already been answered. But in case someone else needs it, you can get the querystrings from ActionFilterAttribute like below:
虽然这个问题已经有了答案。但是如果其他人需要它,您可以从 ActionFilterAttribute 获取查询字符串,如下所示:
public class ApiAuthorizationActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var queryParameters = actionContext.Request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value);
var some_value = queryParameters.ContainsKey("some_key")
? queryParameters["some_key"] : string.Empty;
// Log Action Filter call
base.OnActionExecuting(actionContext);
}
}
But usually how I build API authorizations are using headers and a custom verification logic by adding keys (unique strings) to the database against user/client etc.
但通常我构建 API 授权的方式是使用标头和自定义验证逻辑,方法是针对用户/客户端等向数据库添加密钥(唯一字符串)。
public class ApiAuthorizationActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var headers = actionContext.Request.Headers.ToDictionary(x => x.Key, x => x.Value);
string api_key = headers.ContainsKey("api_key") ? headers["api_key"].FirstOrDefault() : null;
bool canAccessApi = IsValidKey(api_key);
if (!canAccessApi)
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "You do not have access to this API. Please use a valid key.");
// Log Action Filter call
base.OnActionExecuting(actionContext);
}
private bool IsValidKey(string api_key)
{
//Build Access Control Logic here using database keys...
return true;
}
}
回答by David
You should be able to get this information from actionContext.RequestThat is the way to get to the request data.
您应该能够从actionContext.RequestThat is the way to get the request data 中获取此信息。
The posted data is in actionContext.Request.ContentOr if it's a GET request you could get the querystring from actionContext.Request.RequestUri
发布的数据在actionContext.Request.Content或者如果它是 GET 请求,您可以从中获取查询字符串actionContext.Request.RequestUri

