0

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

  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 Request никогда не делает его к этой точке (даже без какого-либо атрибута авторизации). Когда я запускаю два проекта локально, консольное приложение успешно выполняет вызов. Однако, когда я запускаю его на сервере, консольное приложение получает несанкционированное 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 часов и чувствую, что я не добился никакого прогресса. Любая помощь в этом вопросе будет огромной!

+0

Являются ли клиент и сервер использующими одну и ту же конечную точку? Вы запускаете сервер перед клиентом? Соединение состоит из 1) Source IP 2) Destination IP 3) Номер порта. У вас может быть только одно соединение со всеми тремя элементами, одинаковыми. Поэтому обычно сервер запускается первым и подключается к IPAny-адресу с номером порта. Затем клиент подключается к IP-адресу ПК. Таким образом, виртуальное соединение - это действительно два соединения. Сервер IPAny и клиент к IP. ПК настроен на то, что отправка на IP будет перенаправляться на IPAny. – jdweng

+0

@jdweng Я не уверен, что вы подразумеваете под «Как клиент, так и сервер используют одну и ту же конечную точку?». Но чтобы ответить на ваш второй вопрос, да, веб-API запускается до того, как приложение консоли выполнит свой запрос. –

+0

Ваш сервер будет выглядеть как следующая веб-страница, а номером порта может быть любой номер порта (который не заблокирован). Если вы используете свой сервер на ПК, на котором уже запущена веб-страница, вы не можете использовать номер порта 8080 по умолчанию (у вас будет два приложения, работающие с одним и тем же номером порта). https://msdn.microsoft.com/en-us/library/system.net.httplistener(v=vs.100).aspx – jdweng

ответ

0

Из этого SO question я решил, что это, по сути, проблема FQDN. Чтобы «исправить», мне просто пришлось изменить базовый URL-адрес «servername.com/service/» в моем Web.config с «localhost/service /». Как только я это сделал, он прошел безупречно. Мне не нравится мысль об использовании localhost в качестве URL-адреса, но я не могу редактировать значения реестра сервера, поэтому fix provided by Microsoft не будет работать для меня.

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