Могу ли я выдавать себя за клиента, прошедшего проверку подлинности с помощью auth и устанавливать доверенное соединение с SQL Server?

Вот что я пытался сделать

Создайте приложение ASP.NET MVC 3 с проверкой подлинности форм и активным каталогом. Веб-сервер и база данных - это разные физические серверы, следовательно, двойной прыжок.

Я думал, что ответ был в этой старой статье о ограниченном делегировании и протоколе перехода? До сих пор мне не удалось заставить технику работать.

Я тестирую это с моей машины DEV (Windows 7, IIS7) для веб-сервера перед развертыванием в Windows 2008 (IIS7) в производственной настройке. Будет ли Windows 2008 иметь значение?

Что работает и что не удается

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

public void AsUser(Action action)
    {
        using (var id = new WindowsIdentity(User.Identity.Name + @"@example.com"))
        {
            WindowsImpersonationContext context = null;
            try
            {
                context = id.Impersonate();
                action.Invoke();
            }
            catch (Exception ex)
            {
                // ex.Message is The type initializer for System.Data.SqlClient.SqlConnection threw an exception
                // buried inner exeption is Requested registry access is not allowed
            }
            finally
            {
                if (context != null)
                {
                    context.Undo();
                }
            }
        }
    }

Это сбой, с исключением, заставив меня поверить, что у меня есть проблемы с настройкой на моем локальном сервере DEV. Внутреннее исключение составляет Requested registry access is not allowed.

Если я установил точку останова и проверил WindowsIdentity после вызова Impersonate(), я вижу, что для параметра ImpersonationLevel установлено значение Identification. Кажется, это похоже на то, что он настроен неправильно. Кто-нибудь может подтвердить?

Я на правильном пути, и это даже возможно настроить? Любые указатели будут оценены.

Ответ 1

Я думаю, что ты на правильном пути. Вам просто нужно больше усилий по устранению неполадок при настройке перехода по протоколу.

Предполагаю, что вы правильно настроили поставщика членства в Active Directory, чтобы вы могли успешно войти в свою веб-страницу, используя имя и пароль активного каталога. Если это не так, пожалуйста, игнорируйте остальную часть моего ответа:)

Из того, что я видел в вашем вопросе, вы получили свой токен пользователя, используя S4USelf от WindowsIdentity. Затем вы используете S4UProxy для передачи олицетворенного токена на SQL-сервер. Поскольку вы сказали, что получили только ImpersonationLevel.Identification, это означает, что вам не удалось выполнить переход протокола.

Вам нужно понять, что позволить одной машине выполнять переход протокола в домене - очень высокая привилегия. Предоставление сервера для перехода на протокол почти означает, что вы доверяете этому серверу почти как контроллер домена. Вам необходимо сознательно принять это решение в AD, чтобы превратить сервер в эту способность, и вы должны быть администратором domian, чтобы внести это изменение. Если вы этого еще не сделали, вы, вероятно, неправильно настроили свое устройство.

Есть несколько вещей, которые нужно проверить.

Сначала убедитесь, что вы выбрали "Доверять этому компьютеру только делегирование только указанным службам", а затем вы выбрали "Выберите Использовать любой протокол аутентификации" в своей учетной записи службы. Вы можете создать учетную запись домена. Здесь есть ссылка о том, как создать учетную запись службы для ASP.NET. Помните, что вам нужна учетная запись домена. После создания учетной записи службы домена перейдите на вкладку делегирования в этой учетной записи и выберите правильные параметры.

Во-вторых, вам нужно убедиться, что SPN установлены правильно. Я понимаю, что ссылка, которую вы указали, упоминает только SPN вашей учетной записи службы ASP.NET. На самом деле вам также необходимо убедиться, что учетная запись службы на вашем SQL-сервере также установлена ​​правильно. Кроме того, Windows не будет использовать аутентификацию Kerberos. Он вернется к использованию NTLM. Есть много деталей для правильной установки SPN на SQL-сервере. Вы можете сначала проверить здесь и посмотреть, нет ли вам удачи. По моему опыту, большинство администраторов баз данных не знают, как правильно их настроить. Они даже не знают об этом, потому что большинство приложений отлично работают с NTLM. Вам нужно обратить внимание на учетную запись службы SQL Server и номер порта, который он использует.

В-третьих, вам нужно убедиться, что ничего не происходит, отключив делегирование Kerberos. Некоторые уязвимые учетные записи AD по умолчанию не могут быть делегированы. Например, встроенная учетная запись администратора. Таким образом, вам лучше использовать некоторые другие обычные учетные записи пользователей для целей тестирования.

UPDATE

Я только что нашел другую статью, в которой рассказывается, как настроить переход протокола для ASP.NET. Он упомянул, что вам необходимо предоставить права TCB на учетную запись службы IIS, чтобы убедиться, что она может создать тип идентификатора Windows Impersonation. Вы можете сделать снимок.

Ответ 2

Здесь класс, который я использую. Кроме того, вы захотите проверить и посмотреть, имеет ли процесс, который работает в AppPool, достаточное разрешение для олицетворения, так как это такая привилегированная деятельность. Я бы дал учетной записи пользователя, что пул приложений работает под временными привилегиями администратора (конечно, только поле "бокс" ) и посмотреть, работает ли он, чтобы вы знали, является ли это проблемой разрешения.

public class ImpersonationHelper : IDisposable
    {
        private const int LOGON32_LOGON_INTERACTIVE = 2;
        private const int LOGON32_PROVIDER_DEFAULT = 0;
        private WindowsImpersonationContext _impersonationContext;
        private string _userName;
        private string _domain;
        private string _password;

        [DllImport("advapi32.dll")]
        public static extern int LogonUserA(String lpszUserName,
            String lpszDomain,
            String lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int DuplicateToken(IntPtr hToken,
            int impersonationLevel,
            ref IntPtr hNewToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool RevertToSelf();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

        public ImpersonationHelper(string domain, string userName, string password)
        {
            _userName = userName;
            _domain = domain;
            _password = password;
        }

        public void Start()
        {
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            if (RevertToSelf())
            {
                if (LogonUserA(_userName, _domain, _password, LOGON32_LOGON_INTERACTIVE,
                    LOGON32_PROVIDER_DEFAULT, ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        _impersonationContext = tempWindowsIdentity.Impersonate();
                        if (_impersonationContext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                        }
                    }
                }
            }
            if (token != IntPtr.Zero)
                CloseHandle(token);
            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);
        }

        #region IDisposable Members

        void IDisposable.Dispose()
        {
            if (_impersonationContext != null)
            {
                _impersonationContext.Undo();
            }
        }

        #endregion
    }

Ответ 3

Вы включили олицетворение на машине Windows 7 или Windows 2008? В этой статье описывается, как ее настроить. http://technet.microsoft.com/en-us/library/cc730708 (WS.10).aspx. Кроме того, вы используете 32-битную или 64-разрядную версию?

Ответ 4

Вы также должны проверить с администрацией AD, чтобы узнать, разрешено ли олицетворение. Политики наших компаний AD не позволят олицетворению.

Ответ 5

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

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

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

Я думаю, что довольно ясно, что вы не можете передавать свои учетные данные дальше, чем первое соединение.