Обновить:
Я добавил эту ссылку в свой другой ответ, как использовать аутентификацию JWT для ASP.NET Web API здесь для всех, кто интересуется JWT.
Нам удалось применить аутентификацию HMAC для защиты веб-API, и все заработало нормально. HMAC-аутентификация использует секретный ключ для каждого потребителя, который, как пользователь, так и сервер, знают, что hmac хэширует сообщение, следует использовать HMAC256. В большинстве случаев хешированный пароль потребителя используется в качестве секретного ключа.
Сообщение обычно строится из данных в HTTP-запросе или даже из пользовательских данных, которые добавляются в HTTP-заголовок. Сообщение может содержать:
- Отметка времени: время отправки запроса (UTC или GMT)
- HTTP-глагол: GET, POST, PUT, DELETE.
- разместить данные и строку запроса,
- URL
Под капотом аутентификация HMAC будет:
Потребитель отправляет HTTP-запрос на веб-сервер, после построения подписи (вывод хеша hmac) шаблон HTTP-запроса:
User-Agent: {agent}
Host: {host}
Timestamp: {timestamp}
Authentication: {username}:{signature}
Пример для запроса GET:
GET /webapi.hmac/api/values
User-Agent: Fiddler
Host: localhost
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
Сообщение для хеширования для получения подписи:
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
Пример запроса POST со строкой запроса (подпись ниже не верна, просто пример)
POST /webapi.hmac/api/values?key2=value2
User-Agent: Fiddler
Host: localhost
Content-Type: application/x-www-form-urlencoded
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
key1=value1&key3=value3
Сообщение в хеш для получения подписи
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
key1=value1&key2=value2&key3=value3
Обратите внимание, что данные формы и строка запроса должны располагаться по порядку, поэтому код на сервере получает строку запроса и данные формы для построения правильного сообщения.
Когда на сервер поступает HTTP-запрос, для анализа запроса внедряется фильтр действий аутентификации: HTTP-глагол, временная метка, uri, данные формы и строка запроса, а затем на их основе создается сигнатура (используется хэш hmac) с секретом. ключ (хешированный пароль) на сервере.
Секретный ключ получен из базы данных с именем пользователя по запросу.
Затем код сервера сравнивает подпись на запросе с созданной подписью; если равно, аутентификация пройдена, в противном случае она не удалась.
Код для построения подписи:
private static string ComputeHash(string hashedPassword, string message)
{
var key = Encoding.UTF8.GetBytes(hashedPassword.ToUpper());
string hashString;
using (var hmac = new HMACSHA256(key))
{
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
hashString = Convert.ToBase64String(hash);
}
return hashString;
}
Итак, как предотвратить повторную атаку?
Добавьте ограничение для отметки времени, что-то вроде:
servertime - X minutes|seconds <= timestamp <= servertime + X minutes|seconds
(время сервера: время поступления запроса на сервер)
И, кешировать подпись запроса в памяти (используйте MemoryCache, следует ограничивать время). Если следующий запрос приходит с той же подписью, что и предыдущий, он будет отклонен.
Демо-код приведен здесь:
https://github.com/cuongle/Hmac.WebApi
Я бы посоветовал начать с самых простых решений - возможно, в вашем сценарии достаточно простой базовой аутентификации HTTP + HTTPS.
Если нет (например, вы не можете использовать https или нуждаетесь в более сложном управлении ключами), вы можете взглянуть на решения на основе HMAC, предложенные другими. Хорошим примером такого API был бы Amazon S3 ( http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html )
Я написал сообщение в блоге об аутентификации на основе HMAC в ASP.NET Web API. В нем рассматриваются как служба веб-API, так и клиент веб-API, а код доступен на bitbucket. http://www.piotrwalat.net/hmac-authentication-in-asp-net-web-api/
Вот пост о базовой аутентификации в веб-API: http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers/
Помните, что если вы собираетесь предоставлять API сторонним организациям, вы, скорее всего, также будете нести ответственность за доставку клиентских библиотек. Базовая аутентификация имеет существенное преимущество, поскольку она поддерживается на большинстве программных платформ из коробки. HMAC, с другой стороны, не настолько стандартизирован и потребует индивидуальной реализации. Они должны быть относительно простыми, но все же требуют работы.
PS. Также есть возможность использовать HTTPS + сертификаты. http://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/
источник
Вы пробовали DevDefined.OAuth?
Я использовал его для защиты своего WebApi с 2-Legged OAuth. Я также успешно проверил это с клиентами PHP.
С помощью этой библиотеки довольно легко добавить поддержку OAuth. Вот как вы можете реализовать провайдера для ASP.NET MVC Web API:
1) Получите исходный код DevDefined.OAuth: https://github.com/bittercoder/DevDefined.OAuth - новейшая версия обеспечивает
OAuthContextBuilder
расширяемость.2) Создайте библиотеку и сделайте ссылку на нее в своем проекте Web API.
3) Создайте пользовательский конструктор контекста для поддержки построения контекста из
HttpRequestMessage
:4) Используйте это руководство для создания поставщика OAuth: http://code.google.com/p/devdefined-tools/wiki/OAuthProvider . На последнем шаге (Пример доступа к защищенным ресурсам) вы можете использовать этот код в своем
AuthorizationFilterAttribute
атрибуте:Я реализовал свой собственный провайдер, поэтому я не тестировал приведенный выше код (кроме, конечно, того,
WebApiOAuthContextBuilder
который я использую в своем провайдере), но он должен работать нормально.источник
Веб-API представил атрибут
[Authorize]
для обеспечения безопасности. Это может быть установлено глобально (global.asx)Или на контроллер:
Конечно, ваш тип аутентификации может отличаться, и вы можете захотеть выполнить свою собственную аутентификацию, когда это происходит, вы можете найти полезное наследование от атрибута Authorizate и расширение его для удовлетворения ваших требований:
И в вашем контроллере:
Вот ссылка на другую пользовательскую реализацию для авторизаций WebApi:
http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-membership-provider/
источник
AuthorizeAttribute
, так как в разных пространствах имен есть два разных класса с одинаковыми именами: 1. System.Web.Mvc.AuthorizeAttribute -> для контроллеров MVC 2. System.Web.Http.AuthorizeAttribute -> для WebApi.Если вы хотите защитить свой API-интерфейс в режиме «сервер-сервер» (нет переадресации на веб-сайт для двухсторонней аутентификации). Вы можете посмотреть протокол OAuth2 Client Credentials Grant.
https://dev.twitter.com/docs/auth/application-only-auth
Я разработал библиотеку, которая поможет вам легко добавить такую поддержку в ваш WebAPI. Вы можете установить его как пакет NuGet:
https://nuget.org/packages/OAuth2ClientCredentialsGrant/1.0.0.0
Библиотека предназначена для .NET Framework 4.5.
Как только вы добавите пакет в ваш проект, он создаст файл readme в корне вашего проекта. Вы можете посмотреть на этот файл readme, чтобы увидеть, как настроить / использовать этот пакет.
Ура!
источник
в продолжение ответа @ Cuong Le, мой подход к предотвращению повторной атаки будет
// Зашифруем время Unix на стороне клиента с помощью общего закрытого ключа (или пароля пользователя)
// Отправить его как часть заголовка запроса на сервер (WEB API)
// Расшифровываем Unix Time at Server (WEB API), используя общий закрытый ключ (или пароль пользователя)
// Проверяем разницу во времени между Unix Time клиента и Unix Time сервера, не должна превышать x sec
// если идентификатор пользователя / хэш-пароль верны и дешифрованный UnixTime находится в пределах x секунд времени сервера, то это допустимый запрос
источник