Я использую 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!";
}
Как вы могли заметить, я не смог получить доступ к QueryString в любом месте из параметра HttpActionContext и должен был сам его создать. Похоже, они явно удалили QueryString из этого объекта Request. Я не хочу добавлять "токен" к каждому API-методу, чтобы получить его в данных маршрута.
Итак, мои вопросы:
- Является ли QueryString там где-то, и я просто пропущу его? Если нет, любая идея, почему Microsoft не включает его с этим объектом Request? (может быть, это плохо?)
- Есть ли лучший способ справиться с получением токена в AuthorizeAttribute (опять же, не добавляя его к каждому вызову)?
Кстати, я понимаю, что есть другие (вероятно, лучшие) варианты авторизации, такие как Basic Authentication и OAuth, и я не хочу обсуждать эту тему здесь.