2015-02-19 2 views
2

Я имею дело с неприятной проблемой, которая заставила меня разорвать мои волосы. У меня есть консольное приложение C#, которое использует класс HttpListener Microsoft для прослушивания веб-запросов. Идея заключается в том, что консольное приложение запускается в фоновом режиме как UserAccountA (low priv). UserAccountB (Администратор и т. Д.) Появляется, обращается к веб-странице через слушателя и имеет свою личность. То же, что и IIS или WCF. Я считаю, что я работал над Windows 7, но теперь я нахожусь в Windows 8.1, и он снова не работает. Может быть, у меня никогда не было этого, или, может быть, это новый поворот.Как я могу убедиться, что мой уровень олицетворения Windows действителен?

Если я запускаю программу через Visual Studio, я могу получить к ней доступ с помощью Internet Explorer 11. По какой-то причине он просит указать мои локальные учетные данные. Я предполагаю, что это связано с поведением IE11. Как только я ввожу его, он принимает его. Мой код начинается так:

protected virtual void Listen(object o) 
    { 
     HttpListener h = (HttpListener)o; 

     while (h.IsListening && (this.Disposed == false)) 
     { 
      IAsyncResult Result = null; 

      Result = h.BeginGetContext(new AsyncCallback(this.ListenerCallback), h); 

      Result.AsyncWaitHandle.WaitOne(); 
     } 
    } 

И подобран так (сокращенно):

protected virtual void ListenerCallback(IAsyncResult Result) 
    { 
     HttpListener h = (HttpListener)Result.AsyncState; 
     HttpListenerContext context = null; 
     System.Security.Principal.WindowsIdentity identity = null; 

     context = h.EndGetContext(Result); 

     identity = (System.Security.Principal.WindowsIdentity)context.User.Identity; 

     using (System.Security.Principal.WindowsImpersonationContext wic = identity.Impersonate()) 
     { 
      //method call to process request, under impersonation 
     } 
    } 

Я прошел через этот код при использовании двух разных счетов (один для размещения, один для доступа). Я проверял использование этого оператора:

system.security.principal.windowsidentity.getcurrent().name 

То, что текущий идентификатор переходит на переход. Слушатель настроен на запуск с помощью NTLM AuthenticationScheme.

Я полагаю, что сложная часть находится в методе, который вызывается во время олицетворения. Мы делаем немного абстракции, но позвольте мне просто указать на ту часть, которая терпит неудачу. В этом случае мы подключаемся к SQL-серверу с использованием SSPI, поэтому весь смысл олицетворения заключается в том, чтобы захватить существующий вход в систему клиента и изящно получить их в SQL Server. Опять же, прямо сейчас, это все локально для одного компьютера. он даже не находится в домене активного каталога. Все локально, с локальными учетными записями. Он начинается следующим образом:

 System.Data.Common.DbProviderFactory fact = null; 

     if (UseSql()) 
     { 
      fact = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient"); 
     } 

Нет ничего сложного. Мы постоянно используем фабрику поставщиков в другом проекте без каких-либо проблем (но это просто обычное приложение WPF, ничего подобного). Сразу после этого мы установили строку входа SQL с атрибутом SSPI. Но мы даже не добираемся так далеко. Это именно там, где он выходит из строя, с этим сообщением:

Первый шанс исключение типа «System.IO.FileLoadException» произошло в mscorlib.dll

Дополнительная информация: Не удалось загрузить файл или сборку 'System.Data.OracleClient, Version = 4.0.0.0, Culture = neutral, > PublicKeyToken = b77a5c561934e089' или одна из его зависимостей. Либо требуемый уровень олицетворения не был предоставлен, либо предоставленный уровень олицетворения недействителен. (Исключение из HRESULT: 0x80070542)

http://i854.photobucket.com/albums/ab103/srVincentVega/error7_zpsmb1xqrp0.png http://i854.photobucket.com/albums/ab103/srVincentVega/error7_zpsmb1xqrp0.png

Мы не используем Oracle вообще, я предполагаю, что это только первая вещь, которую она barfs, когда он идет и пытается открыть DbProviderFactory. Для меня ключ заключается в том, что уровень уровня олицетворения. В этом конкретном эксперименте обе учетные записи (A & B) являются локальными администраторами. Я обеспечил с помощью локальной политики безопасности, что они могут олицетворять учетные записи после входа в систему.И если я смотрю на свой журнал событий, то олицетворение DOES, похоже, работает ...

Специальные привилегии, назначенные для нового входа.

Тема: Security ID:

PC1 \ ПользовательА

Имя счета: ПользовательА

Учетная запись домена: PC1 Logon ID: 0xC4D0F3F

Привилегии:

SeSecurityPrivilege

SeTakeOwnershipPrivil EGE

SeLoadDriverPrivilege

SeBackupPrivilege

SeRestorePrivilege

SeDebugPrivilege

SeSystemEnvironmentPrivilege

SeImpersonatePrivilege

Я пробовал так много вариаций здесь, что я начинаю мешать собственному анализу. Я в основном вернулся к квадрату и не знаю, как подойти к этому. У кого-нибудь есть советы или подсказки? Кажется, это должно быть очень просто. Я не уверен, почему у меня так много проблем. Может быть, мне просто нужно отказаться от использования DbProviderFactory и пойти с OleDb или что-то еще. Но я не подтвердил, что могу загрузить любые библиотеки во время выполнения после олицетворения. Может быть, это что-то делать. Тем не менее, я был бы очень благодарен за любую помощь.

Спасибо,

Джон

Одна последняя вещь, вот Размножение шаги:

Создание дополнительного пользователя на компьютере. Войдите, чтобы создать профиль. Выйдите из системы и войдите в систему, как обычно. Запуск Visual Studio, как этого вторичного пользователя (есть несколько способов сделать это, Shift + щелкните правой кнопкой мыши на иконке VS), и внутри, сделать C# консольное приложение с этим скелетом:

namespace ConsoleApplication1 
    { 
     class Program 
     { 
      static void Main(string[] args) 
      { 
       using (HttpListener h = new HttpListener()) 
       { 
        h.Prefixes.Add("http://+:8090/"); 

        h.AuthenticationSchemes = AuthenticationSchemes.Ntlm; 

        h.Start(); 

        Console.WriteLine("Running"); 

        HttpListenerContext context = h.GetContext(); 

        System.Security.Principal.WindowsIdentity identity = null; 
        identity = (System.Security.Principal.WindowsIdentity)context.User.Identity; 

        using (System.Security.Principal.WindowsImpersonationContext wic = identity.Impersonate()) 
        { 
         System.Data.Common.DbProviderFactory fact = null; 
         fact = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient"); 
        } 

        Console.ReadLine(); 

        h.Stop(); 
       } 
      } 
     } 
    } 

Debug/Запуск консольное приложение. Просто вызовите Internet Explorer (ваниль, используя основную учетную запись) и получите доступ к этому URL-адресу (http://machinename:8090). Исключение происходит

enter image description here http://i854.photobucket.com/albums/ab103/srVincentVega/error8_zpsilkay0bl.png

+1

В зависимости от того, как вы это делаете, вам может потребоваться добавить локальное правило для прослушивания порта, такого как 8090. Вы можете сделать это при повышенной командной строке: ** netsh http add urlacl url = http: // +: 8090/user = (SecondaryAcctName) ** –

ответ

2

Ну, я читал, как на полпути через и остановились за исключением вы получаете:

A first chance exception of type 'System.IO.FileLoadException' occurred in mscorlib.dll 

Проблема здесь состоит в том, что учетная запись, что вы используете для запуска службы имеет ограниченный доступ к загрузке базовых библиотек .Net, прежде чем он сможет даже выполнить олицетворение.Обычно такая учетная запись, которая используется для размещения службы, имеет права администратора на узле, где размещается служба.

Также для олицетворения вам необходимо предоставить учетной записи службы привилегии сделать это с помощью локальной политики безопасности - Локальные политики - Назначение прав пользователя:

Действовать как часть операционной системы

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

Олицетворять клиент после проверки подлинности

Назначения этой привилегии пользователя позволяет программы, работающие от имени этого пользователя, олицетворять клиент.

Также обратите внимание, если вы используете kerberos вместо NTLM, вам нужно будет установить SPN, а также цели делегирования в AD (Actice Directory).

Я не знаю, поможет ли это вам, но это то, с чем мы столкнулись с выполнением олицетворения/делегирования.

О, да, уровень олицетворения должен быть установлен на делегирование, если вы выполняете более одного прыжка для выполнения олицетворения.

+0

Благодарим вас за идеи. Обе мои тестовые учетные записи являются локальными администраторами, причем две функции SecPol, о которых вы упомянули, включены. Я вышел и вернулся, чтобы убедиться, что они вступили в силу. Проблема сохраняется. Если я обычно запускаю консольное приложение и выполняю запуск, как в Internet Explorer, как и у другого пользователя, он работает. Если я отменил это действие и запускаю - как консольное приложение, и запускаю IE в обычном режиме, то он терпит неудачу. Я выходил из системы и возвращался в другую учетную запись, и то же самое происходило. Это происходит только тогда, когда консольное приложение «работает как», что это происходит –

+0

Возможно, я добавил красную селедку здесь. Я создал полное приложение и установил его для запуска в качестве запланированной задачи Windows как «User B.» Так что это работает в фоновом режиме. Когда я подключаюсь к нему с помощью Internet Explorer, он работает нормально. Я не получаю ошибку. Я подтвердил, что олицетворение работает. Поэтому, возможно, я поддержал некоторые странные проблемы безопасности с функцией «Запускать как». Я думал, что это сработало на Win 7. Либо моя память ошибочна, либо это дополнительная безопасность в 8.1. Я буду отмечать вас как ответ, потому что вы привели меня к этому результату –

Смежные вопросы