我一直在研究 AspNetWebApi 的授权,关于这个主题的信息有点稀疏。
我有以下选择:
- 在查询字符串上传递 API 令牌
- 将 API 令牌作为标头传递
- 使用基本身份验证传递 API 令牌
- 将 API 令牌传递到 json 中的请求负载上。
一般推荐的方法是什么?
我也想知道第 4 点),我将如何检查 AuthorizationFilterAttribute 上的 OnAuthorization 方法中的 json 有效负载以检查 API 令牌是否正确?
我一直在研究 AspNetWebApi 的授权,关于这个主题的信息有点稀疏。
我有以下选择:
一般推荐的方法是什么?
我也想知道第 4 点),我将如何检查 AuthorizationFilterAttribute 上的 OnAuthorization 方法中的 json 有效负载以检查 API 令牌是否正确?
如果您想要一个真正安全的授权选项,那么 OAuth 之类的就是要走的路。这篇博客文章提供了一个使用现已过时的 WCF Web API 的非常详尽的示例,但很多代码是可以挽救的。或者至少,使用本博文中所示的 HTTP 基本身份验证。正如 Aliostad 所指出的,如果您使用基本身份验证路由,请确保您使用的是 HTTPS,以便令牌保持安全。
如果您决定要推出自己的(几乎总是比上述任何一个选项安全得多),那么下面是一个代码示例,如果您使用 HTTP 标头路由,您将需要 AuthorizationHanlder。请注意,Web API 类中处理 UserPrinicipal 的方式很有可能会发生变化,因此此代码仅适用于第一个预览版。您需要像这样连接 AuthorizationHandler:
GlobalConfiguration.Configuration.MessageHandlers.Add(new AuthenticationHandler());
标头令牌代码:
public class AuthenticationHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
var requestAuthTokenList = GetRequestAuthTokens(request);
if (ValidAuthorization(requestAuthTokenList))
{
//TODO: implement a Prinicipal generator that works for you
var principalHelper = GlobalConfiguration.Configuration
.ServiceResolver
.GetService(typeof(IPrincipalHelper)) as IPrincipalHelper;
request.Properties[HttpPropertyKeys.UserPrincipalKey] =
principalHelper.GetPrinicipal(request);
return base.SendAsync(request, cancellationToken);
}
/*
** This will make the whole API protected by the API token.
** To only protect parts of the API then mark controllers/methods
** with the Authorize attribute and always return this:
**
** return base.SendAsync(request, cancellationToken);
*/
return Task<HttpResponseMessage>.Factory.StartNew(
() => new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent("Authorization failed")
});
}
private static bool ValidAuthorization(IEnumerable<string> requestAuthTokens)
{
//TODO: get your API from config or however makes sense for you
var apiAuthorizationToken = "good token";
var authorized = requestAuthTokens.Contains(apiAuthorizationToken);
return authorized;
}
private static IEnumerable<string> GetRequestAuthTokens(HttpRequestMessage request)
{
IEnumerable<string> requestAuthTokens;
if (!request.Headers.TryGetValues("SomeHeaderApiKey", out requestAuthTokens))
{
//Initialize list to contain a single not found token:
requestAuthTokens = new[] {"No API token found"};
}
return requestAuthTokens;
}
}