3

We have a particular SQL Server which we need to access from a thick (.Net 4.0 WPF) client, and the only credentials available to us for that connection is a 'service' account which is effectively an Active Directory account with permission on the SQL Server.

I am using Entity Framework, and ObjectContext, throughout the project, so am continuing with it here. After looking around, I have implemented an impersonation routine based on LogonUserEx, and DuplicateTokenEx, which allows me, via Dependency Injection, to write the following:

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();
}

The constructor of the Impersonate class above calls LogonUserEx and so on. I am explicitly opening and closing the connection as part of a Unit Of Work pattern, which shouldn't be relevant.

Now, via debugging I have found that the token is successfully retrieved for the service account and the user is 'impersonated'. However, as soon as I try to instantiate the ObjectContext I get the following error:

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()

Consequently, it would appear that the account I am impersonating no longer has access or sufficient privelage to load the DLL's from the GAC. The Fusion log is not giving any additional information.

I am not sure how to solve this. I wonder if I am not currently retrieving a token with sufficient privelage. Note that I am providing these paramteres to LogonUserEx: LOGON32_LOGON_NETWORK_CLEARTEXT and LOGON32_PROVIDER_DEFAULT.

Finally, note that this process works absolutely fine on a machine with administrative privelages for the logged on user. It breaks when I run it on a user with a 'normal' account, subject to the usual corporate GPO!

EDIT: Just to include the 'important' part of the impersonation. Notice that I have now swapped to LOGON32_LOGON_UNLOCK, as it is working better. Apologies for the slightly iffy formatting:

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();

Any help greatly appreciated.

Nick.

Nick
  • 2,285
  • 2
  • 14
  • 26
  • Can you post code for your Impersonate class ? – user957902 Nov 04 '11 at 11:32
  • I have added some of the impersonation code. In the mean time, I am testing a potential solution where, during my dependency resolution, I resolve the ObjectContext FIRST, then do the impersonation. This actually looks like it might work... but I'd love to know the details of what is going on under the hood, especially with Fusion etc. – Nick Nov 16 '11 at 08:03
  • You are using DuplicateTokenEx() but you are not using the duplicated resulting token. Could be one part of the problem. – JB. Mar 13 '15 at 20:08

0 Answers0