我们需要从胖(.Net 4.0 WPF)客户端访问特定的SQL Server,我们可用于该连接的唯一凭据是“服务”帐户,该帐户实际上是具有权限的Active Directory帐户在SQL Server上。
我在整个项目中使用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()
因此,我冒充的帐户似乎不再具有从GAC加载DLL的访问权限或足够的privelage。 Fusion日志未提供任何其他信息。
我不知道如何解决这个问题。我想知道我目前是否正在检索具有足够privelage的令牌。请注意,我将这些参数提供给LogonUserEx:LOGON32_LOGON_NETWORK_CLEARTEXT和LOGON32_PROVIDER_DEFAULT。
最后,请注意,此过程在具有登录用户管理权限的计算机上运行正常。当我在具有“普通”帐户的用户上运行它时会中断,这取决于通常的公司GPO!
编辑:只是包括模仿的“重要”部分。请注意,我现在已经交换到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();
非常感谢任何帮助。
尼克。