У меня есть сервер, который предоставляет набор служб REST. Я использую эти службы в клиенте WPF. Все это работает в Интранет, и недавно я решил включить проверку подлинности Windows (до сих пор я использовал другую форму аутентификации), поэтому я могу добиться единого входа. Когда я включил IWA, все службы оставались доступными при вызове через браузер. Проблема в том, что когда я вызываю их с помощью С#-клиента (JsvServiceClient - класс ServiceStack), я получаю Unauthorized exception. Я использую Negotiate, потому что мне нужен Kerberos для олицетворения/делегирования на сервере.
Некоторые мысли сами по себе:
Когда я запускаю скрипач, кажется, что под обложками, когда браузер делает свой первый запрос, он получает также несанкционированный доступ, но после этого он отправляет другой запрос с авторизацией: Negotiate ygMDAuBgorBgEEAYI3AgIKB (этот токен длиннее, я сократил его для простоты) в заголовок. Это приведет к несанкционированному повторению. После этого отправляется третий запрос, который снова имеет авторизацию: вести переговоры в заголовке (но с другим токеном после этого). На этот раз запрос авторизуется и отображаются данные.
Я знаю, как аутентификация, авторизация, кэширование и т.д. Работают в SS, но дело в том, что на сервере не вызывается код (при использовании JsvServiceClient). Я создал HttpModule и добавил его в веб-конфигурацию только для целей отладки. HttpApplication.AuthenticateRequest уволен и сразу после этого вызывается Unathorized. Таким образом, очевидно, что вызов отклонен на этом уровне, и, поскольку SS в основном HttpHandlers запускается для совместной работы, не запускается код сервера (обработчики, не достигнутые вообще).
Возможно, что браузеры выполняют собственную логику, которая обрабатывает WindowsAuth (какое-то рукопожатие или sth) и что эта логика не обрабатывается с использованием клиентов С# в SS. Но поскольку я не уверен в этом, я решил спросить всех гуру здесь.
Может быть, это глупый вопрос, но, по-видимому, я не могу понять это самостоятельно, поэтому любая помощь будет оценена по достоинству.
Добавив RequestFilter
к клиенту, вы можете установить учетные данные для текущего зарегистрированного пользователя, так же, как браузер делает для вас.
Дополнительные сведения см. В разделе CredentialCache.DefaultCredentials
.
JsvServiceClient client = new JsvServiceClient("https://host:port/");
...
client.RequestFilter = req => {
req.Credentials = CredentialCache.DefaultCredentials;
};
Чтобы решить ваши конкретные проблемы:
Возможно, что браузеры выполняют собственную логику, которая обрабатывает WindowsAuth (какое-то рукопожатие или sth) и что эта логика не обрабатывается с использованием клиентов С# в SS.
Да, браузеры обрабатывают аутентификацию Windows самостоятельно при доступе из зоны интрасети. Но базовый HttpWebRequest
в клиенте JsvServiceClient
, JsvServiceClient
, необходимо настроить для отправки учетных данных, как показано выше.
Я знаю, как аутентификация, авторизация, кэширование и т.д. Работают в SS, но дело в том, что на сервере код не вызывается
IIS предоставляет уровень проверки подлинности Windows, а не ServiceStack, поэтому код в службе ServiceStack не вызывается до тех пор, пока не будет выполнена проверка подлинности Windows. Только после этого запрос будет передан обработчику ServiceStack.
Надеюсь это поможет.