Вызов API с поддержкой SSO из Net Core API с использованием явных сетевых учетных данных - PullRequest
0 голосов
/ 06 августа 2020

Я переношу приложение 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, которая, по-видимому, не может быть воссоздана при использовании явных кредитов.

1 Ответ

0 голосов
/ 07 августа 2020

Я получил эту работу с помощью коллеги! Проблема в том, что когда вы используете явные сетевые учетные данные, вы теряете тип аутентификации «Согласование», который требуется нашей конечной точке единого входа. При использовании объекта CredentialCache и явной настройке типа аутентификации Negotiate вызов работает!

var credCache = new CredentialCache { { new Uri("https://example.com"), "Negotiate", new NetworkCredential("svc_acct_user", "svc_acct_password", "mydomain") } };

// Add the cookies to the client to continue the authentication
handler = new HttpClientHandler()
{   
    UseDefaultCredentials = false,
    Credentials = credCache,
    AllowAutoRedirect = true,
    ClientCertificateOptions = ClientCertificateOption.Automatic,
    UseCookies = true,
    CookieContainer = cookieContainer,                        
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...