Аналог WCF 4.0 для RequestInterceptor начального набора WCF REST?
Есть ли в WCF 4.0 аналог / класс / модуль / что-либо еще, аналогичное RequestInterceptor начального набора WCF REST?
3 ответа
Не существует ничего, что отображает 1-1, но вы можете использовать IDispatchMessageInspector из ядра WCF для реализации большинства сценариев, для которых будет работать RequestInspector. Сообщение на http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx содержит некоторую подробную информацию об инспекторах сообщений.
Я вернулся с обновлением.
Мне случается ценить простоту в коде, и после успешного решения этой проблемы я не могу сказать, что предпочитаю ее больше, чем метод Query String. Отбросить один вызов в каждую конечную точку службы, которая вызывает метод AuthN вместе с методом AuthZ, кажется проще, чем некоторые могут поверить.
Во всяком случае, достаточно мнений... на решение. Решение находится прямо под нашими глазами на Stackru по этой ссылке, но не очень хорошо описано в нашем контексте... поэтому я воздаю должное "user634119" за пример кода, найденного здесь: Заголовки в OperationContext
Во-первых, нам нужно добавить serviceBehavior в наш файл web.config:
<behaviors>
<serviceBehaviors>
<behavior>
<serviceAuthenticationManager serviceAuthenticationManagerType="WCF.BasicAuthorization, WCF"></serviceAuthenticationManager>
<serviceAuthorization impersonateCallerForAllOperations="false" principalPermissionMode="Custom" serviceAuthorizationManagerType="WCF.BasicAuthentication, WCF">
</serviceAuthorization>
</behavior>
</serviceBehaviors>
</behaviors>
Затем создайте класс (называемый BasicAuthorization, как указано в блоке serviceBehaviors выше):
//Authorize the call against the URI resource being requested...
public class BasicAuthorization : ServiceAuthorizationManager
{
public override bool CheckAccess(OperationContext operationContext,
ref Message message)
{
//some code
}
}
Затем создайте класс аутентификации:
// Authenticate the header signature as described in my previous post
public class BasicAuthentication : ServiceAuthenticationManager
{
public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(
ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri,
ref Message message)
{
//some code
}
}
В методе Authenticate используйте HttpRequestMessageProperty, чтобы извлечь данные заголовка запроса и выполнить те же 3 шага, которые описаны в моем первом ответе.
Эдуардо, вы спросили: @carlosfigueira: Могу ли я использовать его для реализации подсистемы аутентификации?
Я работаю над той же проблемой, и у меня есть по крайней мере одно решение (описанное ниже) для вас и одно из следующих, основанное на заголовке авторизации (которое, как я полагаю, вы думаете о "перехвате").
Самый простой способ защитить конечную точку на основе модели программирования WCF 4 REST WebHttp:
- Выдайте общий секретный ключ и ключ API каждому клиенту для использования в качестве учетных данных. Ключ API действительно совпадает с именем пользователя.
- Запустите все конечные точки через SSL, чтобы обеспечить безопасность канала / сообщения / данных
- Требуйте от клиентов использования общего секрета для генерации строки хеш-подписи HMAC-SHA1 (или ее эквивалента), которая включает метку времени и их ключ API.
- Требуйте, чтобы клиент передавал все 3 из них как параметры строк запроса в каждом запросе:
- Подпись
- Отметка
- Ключ API
- Пример: https://127.0.0.1/RestEndpoint?Sig={sigString} & ApiKey = {apiKey} & TimeStamp = {timeStamp} & Все остальные ваши параметры здесь...
- На вашей стороне службы внедрите метод аутентификации, который принимает все 3 строки, а затем:
- Ищет ключ API и возвращает общий секретный ключ клиента, который у вас есть в БД или где-то еще.
- Сравните временную метку с DateTime.Now, чтобы убедиться, что запрос не старше 15 минут, чтобы отразить атаки воспроизведения.
- Используя эти 3 строки, воссоздайте строку подписи и сравните вашу с той, которую передал клиент.
- Если они совпадают, запросчик является подлинным.
Теперь лучший способ сделать это - использовать заголовок HTTP-запроса на авторизацию для хранения этих трех строк и иметь глобальный процесс перехватчика, отслеживающий все запросы. Это предотвратит возможность для открытой конечной точки без блока аутентификации (ну, по крайней мере, это, вероятно, менее вероятно).
Проблема с использованием строки запроса для переноса всей этой информации состоит в том, что строка запроса имеет максимальную длину 2 КБ (которая зависит от клиента / браузера), и строка запроса становится действительно трудной для чтения при отладке... но просто привыкните к ней.
Некоторые считают, что более изощренный способ сделать это - модель STS, где требуется, чтобы клиент передал эти 3 строки аутентификации конечной точке службы маркеров безопасности. Ответное сообщение будет передавать обратно токен сеанса, который клиент будет передавать при каждом вызове вместо 3 строк. Это правда, что для клиента нет необходимости генерировать хеш-подпись HMAC при каждом вызове, но серверная сторона все еще должна аутентифицировать токен, и концепция сеанса нарушает чистое поведение RESTful без сохранения состояния.
Я постараюсь опубликовать блоки кода, которые реализуют как строку запроса, так и методологию заголовка auth.