Если вам нужен действительно безопасный вариант авторизации, вам подойдет что-то вроде OAuth. В этом сообщении в блоге тщательный пример с использованием устаревшего веб-API WCF, но большую часть кода можно спасти. Или, по крайней мере, используйте базовую аутентификацию HTTP, как показано в этом запись в блоге. Как отмечает Алиостад, убедитесь, что вы используете HTTPS, если вы идете по маршруту базовой аутентификации, чтобы токен оставался в безопасности.
Если вы решите, что хотите свернуть свой собственный (который почти всегда будет гораздо менее безопасным, чем любой из вышеперечисленных вариантов), то ниже приведен пример кода того, что вам понадобится для AuthorizationHanlder, если вы идете по маршруту HTTP-заголовка. Имейте в виду, что существует большая вероятность того, что способ обработки UserPrinicipal в классах веб-API может измениться, поэтому этот код подходит только для первого предварительного выпуска. Вам нужно будет подключить 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;
}
}
person
Sixto Saez
schedule
03.05.2012