Я переношу приложение WinForms на API. Net Core (3.1), и у меня возникли проблемы с функцией, которая вызывает API-интерфейс, защищенный SSO, в нашей сети.
В приложении WinForms у меня было следующее:
public async void Authenticate()
{
var wi = System.Security.Principal.WindowsIdentity.GetCurrent();
var wic = wi.Impersonate();
try
{
// Initial request to grab cookies and redirect endpoint
var apiEndPoint = $"https://{_host}{_apiPath}";
var cookieRedirectRequest = new HttpRequestMessage(HttpMethod.Get, apiEndPoint);
var response = await _httpClient.SendAsync(cookieRedirectRequest);
if (response != null)
{
var cookieContainer = new CookieContainer();
foreach (var cookie in response.Headers.GetValues("Set-Cookie"))
{
var parsedCookie = cookie.ToCookie();
parsedCookie.Domain = TARGET_DOMAIN;
cookieContainer.Add(parsedCookie);
}
var redirectURL = response.Headers.GetValues("Location").FirstOrDefault();
// Add the cookies to the client to continue the authentication
_httpClient = new HttpClient(new HttpClientHandler()
{
UseDefaultCredentials = true,
AllowAutoRedirect = true,
ClientCertificateOptions = ClientCertificateOption.Automatic,
UseCookies = true,
CookieContainer = cookieContainer
});
// Second request to grab code and state values
var codeAndStateRequest = new HttpRequestMessage(HttpMethod.Get, redirectURL);
response = await _httpClient.SendAsync(codeAndStateRequest);
...
Первоначальный вызов API перенаправляет нас на страницу SSO-аутентификации. Я использую файлы cookie из этого первоначального ответа, чтобы создать свой собственный запрос, чтобы я мог передать правильные учетные данные и получить обратно соответствующие токены SSO (ответ на вызов SendSyn c в последней строке возвращает токены), который я затем используйте для аутентификации при будущих запросах к API.
Я пытаюсь воссоздать эту функцию в. NET Core с помощью учетной записи службы, и вместо того, чтобы выполнять олицетворение WindowsIdentity, я пытаюсь явно установите свойство NetworkCredentials моего HttpClientHandler:
handler = new HttpClientHandler()
{
UseDefaultCredentials = false,
Credentials = new NetworkCredential("svc_acct_username", "svc_act_pass", "mydomain"),
AllowAutoRedirect = true,
ClientCertificateOptions = ClientCertificateOption.Automatic,
UseCookies = true,
CookieContainer = cookieContainer,
};
Однако ответ, который я получаю на свой второй запрос, - 401.
Это соответствует тому, что я использовал для получения мое исходное приложение - сначала я бы получил 401 с заголовком «WWW-Authenticate: Negotiate», но затем был бы автоматический c последующий запрос, в который были переданы сетевые учетные данные, и я бы получил 200. Я Я не получаю этот второй запрос с кредитами в. Net Core.
Я пробовал Credentials Cach Предлагаемое здесь решение: https://github.com/dotnet/runtime/issues/24490 Но это не сработало.
Заранее благодарим вас за любую помощь, которую вы можете мне оказать. Я застрял!
Быстрое редактирование: я могу воссоздать поведение. Net Core в моем приложении WinForms, просто явно установив свойство Credentials HttpClientHandler и установив UseDefaultCredentials = false. Итак, происходит некоторая магия c, устанавливающая UseDefaultCredentials, которая, по-видимому, не может быть воссоздана при использовании явных кредитов.