在自定义AuthorizeAttribute中访问QueryString

我正在使用Web API并设置了一个简单的身份validation和授权机制,其中调用者在查询字符串中传递我发给他们的令牌。 所以他们提交的请求如下:

https://mysite.com/api/Ping?token=[issued-token] 

我有一个像这样的ApiAuthorizeAttribute:

 public class ApiAuthorizeAttribute : System.Web.Http.AuthorizeAttribute { public ApiPermission Permission { get; set; } public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext) { switch (Permission) { case ApiPermission.None: return; case ApiPermission.Write: case ApiPermission.Read: string query = actionContext.Request.RequestUri.Query; var nvc = System.Web.HttpUtility.ParseQueryString(query); string token = nvc["token"]; // (my code to map the token to an Authorization for the request) ApiAuthorization auth = ApiToken.GetAuthorization(token); if (auth != null && auth.HasPermission(Permission)) return; HandleUnauthorizedRequest(actionContext); return; default: throw new ArgumentException("Unexpected Permission"); } } } 

然后我可以像这样装饰我的API。 注意:这只是一个示例,真正的呼叫将从其帐户读取数据(帐户标识符在其令牌中加密)并返回它。

 ///  /// Ping service that requires a Token with Read permission /// Returns "Success!" ///  [ApiAuthorize(Permission = ApiPermission.Read)] [HttpGet] public string Ping() { return "Success!"; } 

您可能会注意到,我无法从HttpActionContext参数访问QueryString,并且必须自己构建它。 看起来他们从这个Request对象中明确地删除了QueryString。 我不想将“令牌”添加到每个API方法中,以便在路由数据中获取它。

所以我的问题是:

  1. QueryString是否在某处,我只是错过了它? 如果没有,任何想法为什么微软不包含这个Request对象? (也许这可能是件坏事?)
  2. 有没有更好的方法来处理在AuthorizeAttribute中获取令牌(再次,不将其添加到每个调用)?

顺便说一句,我意识到还有其他(可能更好)的授权选项,如基本身份validation和OAuth,我不想在这里讨论这个话题。

虽然Adam Tal的答案非常有效,但在Web API新世界秩序中,您真的不想使用System.Web命名空间中的任何内容; 实际上你甚至不想引用它。 唉,您可以从GetQueryNameValuePairs()扩展方法获取查询字符串。 这将让你削减System.Web船锚松散,仍然得到你需要的。

 var queryString = actionContext.Request .GetQueryNameValuePairs() .ToDictionary(x => x.Key, x => x.Value); 

尝试

 using System.Web; HttpContext.Current.Request.QueryString