我正在使用 Web API 并设置了一个简单的身份验证和授权机制,调用者在其中传递了我在查询字符串中颁发给他们的令牌。所以他们提交了如下请求:
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。注意:这只是一个例子,真正的调用会从他们的账户中读取数据(账户标识符在他们的令牌中加密)并返回。
/// <summary>
/// Ping service that requires a Token with Read permission
/// Returns "Success!"
/// </summary>
[ApiAuthorize(Permission = ApiPermission.Read)]
[HttpGet]
public string Ping()
{
return "Success!";
}
正如您可能注意到的,我无法从 HttpActionContext 参数的任何地方访问 QueryString 并且必须自己构建它。他们似乎从这个 Request 对象中明确删除了 QueryString 。我不想将它添加到每个 API 方法中,以便在路由数据中获取它。
所以我的问题是:
- QueryString 是否在某处而我只是想念它?如果没有,知道为什么微软不将它包含在这个 Request 对象中吗?(即,也许这是一件坏事?)
- 有没有更好的方法来处理在 AuthorizeAttribute 中获取令牌(同样,不将其添加到每个调用中)?
顺便说一句,我意识到还有其他(可能更好)的授权选项,例如基本身份验证和 OAuth,我不想在这里讨论这个话题。