Олицетворение работает с локальным общим файлом, но не работает с удаленным - PullRequest
0 голосов
/ 03 января 2019

У меня есть веб-приложение .net / c # (web api) с аутентификацией Windows. Служба размещена на моем локальном компьютере, IIS 10. Идентификатор пула приложений, установленный для меня, в данный момент зарегистрирован в Windows. Компьютер находится в домене активного каталога.

Я хочу получить доступ к общему файлу, используя учетную запись, которая в данный момент вошла в приложение. Файл имеет соответствующие разрешения. Для этого я использую олицетворение так:

    if (HttpContext.Current.User.Identity is WindowsIdentity windowsIdentity)
       {
           using (windowsIdentity.Impersonate())
           {
                FileStream stream = new FileStream(@"\\server\share\file.ext", FileMode.Open, FileAccess.Read);
           }
       }

Я вхожу в систему с текущей учетной записью Windows, так же, как установлено в удостоверении пула приложений. Это прекрасно работает с общим файлом на локальном компьютере, где размещено приложение. Но не работает с удаленным общим файлом, расположенным на другом компьютере. Другой компьютер также находится в домене активного каталога.

С хост-компьютера я могу получить доступ к общему файлу с помощью проводника Windows или моего браузера. Кроме того, если я не выдаю себя за пользователя, .net пытается получить доступ к общему файлу с учетной записью удостоверения пула приложений (установленному для того же пользователя, я), и это успешно выполняется как для локальных, так и для удаленных файлов.

Он также работает с олицетворенной идентификацией, полученной из метода LogonUser от advapi32.dll. Но для этого требуется пароль пользователя, и я не хочу запрашивать пароль у пользователя, уже вошедшего в приложение.

Что я делаю не так?

Обновление : если общий файл находится на хост-компьютере, то событие входа в систему, созданное окнами (вкладка безопасности в средстве просмотра событий), показывает нужного пользователя. Если общий файл находится на другом компьютере, то событие входа в систему, созданное Windows на этом компьютере, показывает анонимный пользователь. Итак, аккаунт как-то потерян.

Обновление 2 : Олицетворение работает, если я запускаю сайт на IIS, как localhost (localhost in url). Но если я запускаю его, используя ip или имя сайта, он перестает работать.

Обновление 3 : Wireshark отображает запрос на получение заявки (для доступа к общему файловому серверу) для делегирования, с ошибкой «KRB5KDC_ERR_BADOPTION NT Status: STATUS_NOT_FOUND». В AD разрешено делегирование для пользователя пула приложений. Один и тот же билет (для cifs / fileshareservername) без делегирования может быть успешно получен (показывает wireshark) при выполнении команды Dir в cmd. Кажется, проблема в нашей эры.

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

Он начал работать для меня со следующими настройками:

IIS:

  1. Идентификатор пула приложений, установленный для конкретного пользователя (скажем, IISUser).
  2. Проверка подлинности Windows включена для сайта IIS.Режим ядра включен (важно!).

Все остальное происходит в Active Directory:

  1. Компьютер с общими файлами имеет имя участника-службы: cifs /% computer_name%.
  2. Хост-компьютер (на котором установлен IIS) является доверенным для делегирования.Вкладка «Делегирование» -> Доверять этот компьютер для делегирования только указанным службам -> Использовать любой протокол аутентификации.Затем выберите имя участника-службы из пункта 1. Важно: вы должны выбрать имя участника-пользователя компьютера, а не имя участника-службы IISUser.
  3. IISUser является доверенным для делегирования имени участника-службы из пункта 1.
0 голосов
/ 03 января 2019

Не могу точно сказать, что то, что вы делаете, неправильно, но я могу сказать вам, что я сделал, чтобы сделать очень похожую вещь. Мой сайт .Net обычно не имеет WindowsLogin, поэтому мне пришлось сделать дополнительный прыжок, который, я думаю, вы могли бы сделать, чтобы облегчить то же самое, но, возможно, не самый лучший ответ.

При входе в систему (в моем членстве Provider) я запускаю этот код:

try
{
    if (LogonUser(user,domain,password, [AD_LOGIN], 
                   LOGON32_PROVIDER_DEFAULT, ref handle))
    {
        IntPtr tokenDuplicate = IntPtr.Zero;

       if (DuplicateToken(handle, SecurityImpersonation,
             ref tokenDuplicate) != 0)
       {
          // store off duplicate token here
       }
    }
}
finally
{
    if (handle != IntPtr.Zero)
    {
        CloseHandle(handle);
    }
}

затем, когда вам нужно выдать себя за другого, сделайте следующее:

var context = WindowsIdentity.Impersonate(tokenDuplicate);
try
{
    // do your file access here
}
finally
{
    context.Dispose();
}

Мне пришлось сделать забавное преобразование этой переменной tokenDuplicate. Это целочисленное значение, но указывающее на определенный адрес памяти, где хранится информация о токене. Он остается в силе, пока вы вошли в систему.

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

...