Как получить Windows Authenticated пользователя в C # Web API синхронизации и асинхронности - PullRequest
0 голосов
/ 29 марта 2019

Мне нужна помощь, чтобы решить эту проблему, с которой я застрял на работе.У нас есть веб-API в .NET Framework 4.7.1 (он имеет API, приложение, ядро, тестовые проекты).Проект сложный и содержит код от 10+ разных разработчиков.Мы используем Microsoft Dynamics D365 8.2 OnPremise для наших данных, поэтому в любое время, когда нам приходится выполнять операции CRUD, мы должны соединяться с CRM через их код SDK.Проект размещен на IIS 8.5 Windwos Server 2012 R2, а внешний интерфейс - Angular 5 (мы используем опцию withCredentials для вызовов API).У нас включена проверка подлинности Windows и олицетворение ASP.NET, а все другие методы проверки подлинности отключены.В нашем коде C # в 99% случаев, когда мы подключаемся к нашему CRM SDK, нам также нужно выдавать себя за пользователя, мы делаем это, передавая имя пользователя, чтобы получить Guid.Этот код работал долгое время, пока совсем недавно мы не узнали, что наш код неправильно настраивает пользователя.

Код, который иногда не работает:

System.Security.Principal.WindowsPrincipal(System.Security.Principal.WindowsIdentity.GetCurrent()).Identity.Name

В большинстве случаев мы получаем правильного пользователя, но иногда он заставляет пользователя запустить процесс в IIS.

Я также пытался:

System.Web.HttpContext.Current.User.Identity.Name

Но иногда это ноль

* 1012И, наконец, я подумал, что решение было:
System.Threading.Thread.CurrentPrincipal.Identity.Name

Это сработало для многих моих тестов.Проблема в том, что через некоторое время (я думаю, что если служба вызывается внутри Task.Run (() => {}), блок выдает ошибку: System.ObjectDisposedException: безопасный дескриптор закрыт

Я прочитал следующие статьи, чтобы помочь: официальная документация о .net web api: https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

В этом посте говорится об очень похожей проблеме: https://social.msdn.microsoft.com/Forums/vstudio/en-US/bca4556e-53f3-427c-a51a-9b955e2395e2/how-to-get-the-windows-identity-through-web-api-2-in-a-intranetlocal-network-setup?forum=wcf#89485c63-352b-434a-862b-8c5f4cec620c

Эти два поста о Safe Handleбыло закрыто: Сохранение принципала внутри фонового рабочего элемента в очереди Установить Thread.CurrentPrincipal Асинхронно?

, что заставило меня попытаться написать какой-то код вроде (сохранил System.Threading.Thread.CurrentPrincipal.Identity.Name работает, но все еще выдает ошибку):

    ClaimsPrincipal principal = new ClaimsPrincipal(Thread.CurrentPrincipal);
    // Save Total Payment Stream Payments (Async)
    Task.Run(() =>
    {
        HttpContext.Current.User = new ClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", principal.Identity.Name) }, "auth")));
        Thread.CurrentPrincipal = principal;
        SaveTotalPaymentStream(opportunityTermId);
    });

Любые идеи или предложения по этому поводу были бы хорошими. Может быть, мне нужно что-то более сложное, например, создание собственного Принципала или, может быть, я 'Я просто испортил Task.Run (который я наконец-то подумал, что понял это ...)

Спасибо!

1 Ответ

0 голосов
/ 15 мая 2019

Что я узнал, так это то, что получить зарегистрированного пользователя в асинхронных методах может быть довольно сложно.HttpContext довольно надежен для кода синхронизации, и когда мне абсолютно необходимо войти в систему, я просто передаю переменную в свой асинхронный код.

...