Могу ли я выдать себя за клиента, прошедшего проверку подлинности с помощью форм, и установить надежное соединение с SQL Server?
Вот что я пытался сделать
Создайте приложение ASP.NET MVC 3 с проверкой подлинности форм и членством в активном каталоге. Веб-сервер и база данных - это разные физические серверы, следовательно, двойной переход.
Я думал, что ответом была эта старая статья об ограниченном делегировании и передаче протокола? До сих пор я не смог заставить технику работать.
Я тестирую это с моего компьютера DEV (Windows 7, IIS7) для веб-сервера перед развертыванием в Windows 2008 (IIS7) в производственной настройке. Будет ли Windows 2008 иметь значение?
Что работает, а что нет
Я могу войти через формы авторизации и членство в 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
, Это похоже на подсказку, что он настроен неправильно. Кто-нибудь может подтвердить?
Я на правильном пути, и это вообще возможно настроить? Любые указатели будут оценены.
5 ответов
Я думаю, что вы на правильном пути. Вам просто нужно больше работы по устранению неполадок в настройке перехода протокола.
Я предполагаю, что вы правильно настроили поставщика членства в Active Directory, чтобы вы могли успешно войти на свою веб-страницу, используя имя пользователя и пароль активного каталога. Если это не так, пожалуйста, игнорируйте остальную часть моего ответа:)
Из того, что я увидел в вашем вопросе, вы получили токен своего пользователя с помощью S4USelf от WindowsIdentity. Затем вы используете S4UProxy для передачи олицетворенного токена серверу SQL. Так как вы сказали, что получили ImpersonationLevel.Identification
только это означает, что вы не смогли сделать переход по протоколу.
Вы должны понимать, что разрешение одной машине выполнять переключение протокола в домене - это очень высокая привилегия. Предоставление серверу для перехода по протоколу почти означает, что вы доверяете этому серверу почти как контроллеру домена. Вам нужно сознательно принять это решение в AD, чтобы сервер имел такую возможность, и вы должны быть администратором domian, чтобы внести это изменение. Если вы этого не сделали, вы, вероятно, неправильно настроили свою вещь.
Есть пара вещей, чтобы проверить.
Сначала убедитесь, что вы выбрали "Доверять этот компьютер для делегирования только указанным службам", а затем "выберите Использовать любой протокол проверки подлинности" в своей учетной записи службы. Вы можете создать учетную запись домена. Вот ссылка на то, как создать служебную учетную запись для ASP.NET. Помните, вам нужна учетная запись домена. После создания учетной записи службы домена обязательно перейдите на вкладку делегирования этой учетной записи и выберите правильные параметры.
Во-вторых, вам нужно убедиться, что имена участников-служб установлены правильно. Я понимаю, что в размещенной вами ссылке упоминается только имя участника-службы вашей учетной записи службы ASP.NET. На самом деле, вам также необходимо убедиться, что учетная запись службы на вашем сервере SQL также настроена правильно. Иными словами, Windows вообще не будет использовать аутентификацию Kerberos. Он вернется к использованию NTLM. Существует множество деталей для правильной настройки имени участника-службы на сервере SQL. Вы можете проверить здесь сначала и посмотреть, если вам повезет. По моему опыту, большинство администраторов баз данных не знают, как их правильно настроить. Они даже не знают об этом, потому что большинство приложений нормально работают с NTLM. Вы должны обратить внимание на учетную запись службы сервера SQL и номер порта, который она использует.
В-третьих, вам нужно убедиться, что ничто не отключает делегирование Kerberos. Некоторые конфиденциальные учетные записи AD по умолчанию запрещены для делегирования. Например, встроенная учетная запись администратора. Таким образом, вам лучше использовать некоторые другие обычные учетные записи пользователей для целей тестирования.
ОБНОВИТЬ
Я только что нашел другую статью, в которой рассказывается, как настроить переход по протоколу для ASP.NET. В нем упоминалось, что вам необходимо предоставить право TCB учетной записи службы IIS, чтобы убедиться, что она может создать Impersonation
введите WindowsIdentity. Вы можете дать ему шанс.
Здесь класс я использую. Кроме того, вы захотите проверить и посмотреть, достаточно ли у процесса, под которым запущен AppPool, разрешение на олицетворение, поскольку это такое привилегированное действие. Я хотел бы указать учетной записи пользователя, что пул приложений работает с временными правами администратора (конечно, только для dev-блока), и посмотреть, работает ли он, чтобы вы знали, если это проблема с разрешениями.
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
}
Вам также следует проконсультироваться с администрацией AD, чтобы узнать, разрешено ли олицетворение. Политика AD моей компании не допускает олицетворения.
Включили ли вы олицетворение на компьютере с Windows 7 или Windows 2008? В этой статье рассказывается, как его настроить. http://technet.microsoft.com/en-us/library/cc730708%28WS.10%29.aspx. Кроме того, вы используете 32-разрядную или 64-разрядную версию?
Я думаю, что вы определили проблему, но никто не упомянул ее. Проблема "двойного прыжка" не позволит вам сделать это. Это невозможно. Есть много людей, которые написали об этом, таких как Скотт Форсайт.
Когда вы проходите аутентификацию на сервере IIS с помощью встроенной аутентификации, это использует ваш первый "прыжок". Когда IIS пытается получить доступ к сетевому устройству, это будет двойной или второй переход, который не разрешен. IIS, в свою очередь, не может передать эти учетные данные следующему сетевому устройству, в противном случае разработчик или администратор может злоупотребить вашими учетными данными и использовать их так, как этого не ожидал посетитель сайта.
Это не происходит при анонимном доступе или отключении олицетворения, потому что в этом случае IIS заботится о вашей аутентификации, а затем использует другого пользователя для локального или сетевого доступа. Это означает, что удостоверение пула приложений или анонимный пользователь могут выполнить сетевой вызов в качестве первого прыжка.
Я думаю, что совершенно ясно, что вы не можете передать свои учетные данные дальше, чем первое соединение.