LogonUserEx, DuplicateTokenEx для олицетворения с ObjectContext в C # - PullRequest
3 голосов
/ 04 ноября 2011

У нас есть определенный SQL Server, к которому нам нужен доступ из толстого (.Net 4.0 WPF) клиента, и единственными доступными нам учетными данными для этого подключения является учетная запись «службы», которая фактически является учетной записью Active Directory с разрешения на сервере SQL.

Я использую Entity Framework и ObjectContext во всем проекте, поэтому продолжаю его здесь. После осмотра я реализовал подпрограмму олицетворения на основе LogonUserEx и DuplicateTokenEx, которая позволяет мне с помощью внедрения зависимостей написать следующее:

using (container.Resolve<Impersonate>())
using (var context = container.Resolve<MyObjectContext>())
{
   context.Connection.Open();
   //Do some work with the data as the service account.
   context.Connection.Close();
}

Конструктор класса Impersonate выше вызывает LogonUserEx и так далее. Я явно открываю и закрываю соединение как часть шаблона единицы работы, который не должен быть релевантным.

Теперь с помощью отладки я обнаружил, что токен успешно получен для учетной записи службы, а пользователь «выдан за другого». Однако, как только я пытаюсь создать экземпляр ObjectContext, я получаю следующую ошибку:

System.TypeInitializationException: The type initializer for 'EntityBid' threw a
n exception. ---> System.IO.FileLoadException: Could not load file or assembly '
System.Data.Entity.dll' or one of its dependencies. Either a required impersonat
ion level was not provided, or the provided impersonation level is invalid. (Exc
eption from HRESULT: 0x80070542)
   at System.Runtime.InteropServices.Marshal.GetHINSTANCE(RuntimeModule m)
   at System.Runtime.InteropServices.Marshal.GetHINSTANCE(Module m)
   at EntityBid.initEntryPoint()
   at EntityBid.internalInitialize()
   at EntityBid..cctor()
   --- End of inner exception stack trace ---
   at EntityBid.Trace(String fmtPrintfW, String a1)
   at System.Data.EntityUtil.ProviderExceptionWithMessage(String message, Except
ion inner)
   at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean op
enCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection
, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnection
OnFailure)
   at System.Data.EntityClient.EntityConnection.Open()
   at Core.Security.TestHarness._2.Class1..ctor()

Следовательно, может показаться, что учетная запись, которую я олицетворяю, больше не имеет доступа или достаточного привилегированного уровня для загрузки DLL из GAC. Журнал Fusion не дает никакой дополнительной информации.

Я не уверен, как это решить. Интересно, не получаю ли я токен с достаточным количеством привилегий? Обратите внимание, что я предоставляю следующие параметры LogonUserEx: LOGON32_LOGON_NETWORK_CLEARTEXT и LOGON32_PROVIDER_DEFAULT.

Наконец, обратите внимание, что этот процесс работает абсолютно нормально на компьютере с привилегиями администратора для вошедшего в систему пользователя. Он ломается, когда я запускаю его на пользователя с «обычной» учетной записью, при условии обычного корпоративного объекта групповой политики!

РЕДАКТИРОВАТЬ: Просто чтобы включить «важную» часть подражания. Обратите внимание, что я теперь поменялся на LOGON32_LOGON_UNLOCK, так как он работает лучше. Извиняюсь за немного ненадежное форматирование:

if (LogonUserEx(dUser, dDomain, dPassword, LOGON32_LOGON_UNLOCK,
                                  LOGON32_PROVIDER_DEFAULT, out token, IntPtr.Zero,    IntPtr.Zero, IntPtr.Zero, IntPtr.Zero))
{

                        if (DuplicateTokenEx(token, MAXIMUM_ALLOWED, ref sa, SECURITY_IMPERSONATION_LEVEL.SecurityDelegation, TOKEN_TYPE.TokenPrimary, out tokenDuplicate))
                        {
                            m_ImpersonatedUser = new WindowsIdentity(token);

                            _windowsImpersonationContext = m_ImpersonatedUser.Impersonate();

Любая помощь с благодарностью.

Ник.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...