Как передать олицетворенного пользователя в вызове Web API из Консольного приложения с проверкой подлинности Windows?

У меня есть Консольное приложение и проект Web API 2, оба работают на одном сервере. Я настроил свое консольное приложение для вызова конечной точки RESTful в моем веб-API с помощью HttpClient при олицетворении учетной записи домена.

            Console.WriteLine("Setting up impersonator.");
            using (new Impersonator(accountUsername, accountDomain, accountPwd))
            {
                Console.WriteLine("Impersonator set up.");

                HttpClientHandler handler = new HttpClientHandler();
                handler.UseDefaultCredentials = true;

                Console.WriteLine("Executing as: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name);

                using (var client = new HttpClient(handler))
                {
                    client.BaseAddress = new Uri(serviceBaseUrl);
                    client.DefaultRequestHeaders.Accept.Clear();
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                    HttpResponseMessage response = await client.GetAsync("api/resource/3/");
                    Console.WriteLine(response.ToString());
                    if (response.IsSuccessStatusCode)
                    {
                        result = await response.Content.ReadAsAsync<ResourceType>();
                    }
                }

                if (result != null)
                {
                    // Do something...
                }
            }

Я не думаю, что фактическая конечная точка имеет отношение к этому вопросу, так как запрос Http никогда не достигает этого пункта (даже без какого-либо атрибута авторизации). Когда я запускаю два проекта локально, консольное приложение успешно выполняет вызов. Однако, когда я запускаю его на сервере, консольное приложение получает 401 несанкционированный. Я добавил некоторые записи в мой конвейер веб-API для регистрации информации HttpContext.Current.User.

    protected void Application_BeginRequest()
    {
        var currentContext = HttpContext.Current;
        ILogHelper _logger = new LogHelper("System");

        _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "BeginRequest System Principal Name: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name);
        _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "BeginRequest Is User Null? " + (currentContext.User == null? "YES":"NO"));

        if (currentContext.User != null)
        {
            _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "BeginRequest User: " + currentContext.User.Identity.Name);
            _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "BeginRequest User Authenticated: " + currentContext.User.Identity.IsAuthenticated.ToString());
        }
    }

    protected void Application_AuthenticateRequest()
    {
        var currentContext = HttpContext.Current;
        ILogHelper _logger = new LogHelper("System");

        _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "AuthenticateRequest System Principal Name: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name);
        _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "AuthenticateRequest Is User Null? " + (currentContext.User == null ? "YES" : "NO"));

        if (currentContext.User != null)
        {
            _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "AuthenticateRequest User: " + currentContext.User.Identity.Name);
            _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "AuthenticateRequest User Authenticated: " + currentContext.User.Identity.IsAuthenticated.ToString());
        }
    }

    protected void Application_AuthorizeRequest()
    {
        var currentContext = HttpContext.Current;
        ILogHelper _logger = new LogHelper("System");

        _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "AuthorizeRequest System Principal Name: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name);
        _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "AuthorizeRequest Is User Null? " + (currentContext.User == null ? "YES" : "NO"));

        if (currentContext.User != null)
        {
            _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "AuthorizeRequest User: " + currentContext.User.Identity.Name);
            _logger.LogLine(NLog.LogLevel.Info, LogHelper.Tier.Business, "AuthorizeRequest User Authenticated: " + currentContext.User.Identity.IsAuthenticated.ToString());
        }
    }

При локальном запуске олицетворенный пользователь регистрируется в «AuthenticateRequest» и «AuthorizeRequest». Но когда он запускается на сервере, пользователь теряет значение в течение всего процесса.

У меня включена проверка подлинности и олицетворение Windows в IIS (все остальное отключено). Я работаю над этим более 40 часов и чувствую, что не добился никакого прогресса. Любая помощь в этом вопросе будет огромной!

 jdweng16 июн. 2016 г., 17:41
Ваш сервер будет выглядеть следующим образом, а номер порта может быть любым номером порта (который не заблокирован). Если вы используете свой сервер на компьютере, на котором уже есть веб-страница, вы не можете использовать номер порта по умолчанию 8080 (у вас будет два приложения с одинаковым номером порта).msdn.microsoft.com/en-us/library/...
 Willy_B16 июн. 2016 г., 14:58
@jdweng Я не уверен, что вы имеете в виду под словом «Клиент и сервер используют одну и ту же конечную точку?». Но, чтобы ответить на ваш второй вопрос, да, веб-API работает до того, как консольное приложение сделает запрос.
 jdweng16 июн. 2016 г., 14:13
И клиент, и сервер используют одну и ту же конечную точку? Вы запускаете сервер раньше клиента? Соединение состоит из 1) исходного IP-адреса 2) целевого IP-адреса 3) номера порта. У вас может быть только одно соединение, при этом все 3 элемента одинаковы. Поэтому обычно сервер запускается первым и подключается к IP-адресу с номером порта. Затем клиент подключается к IP-адресу ПК. Таким образом, виртуальное соединение - это действительно два соединения. Сервер к IPAny и клиент к IP. ПК настроен так, что отправка на IP будет перенаправлена ​​на IPAny.

Ответы на вопрос(1)

Решение Вопроса

ТАК вопросЯ определил, что это проблема FQDN. Чтобы «исправить», мне просто нужно было изменить базовый URL «servername.com/service/» в моем файле Web.config с помощью «localhost / service /». Как только я это сделал, все прошло без нареканий. Мне не нравится мысль об использовании localhost в качестве URL, но я не могу изменить значения реестра сервера, поэтомуисправление предоставлено Microsoft не будет работать для меня.

Кроме того, оказывается, что мне не нужно включать олицетворение на моем веб-сайте API в IIS. Теперь у меня включена только аутентификация Windows.

 Anton12 мар. 2018 г., 15:14
Чувак, ты спас мой день. Спасибо.

Ваш ответ на вопрос