.net – Why, when I impersonate within a WCF service, can the service not load System.Transactions when I try to run a LINQ to SQL query

netSecuritysql servertransactionswcf

I have a WCF service, hosted in IIS 7.0 that needs to run database queries. In order to get the right permissions to do this I am impersonating within the service as follows:

Code

[OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
public void MyOperation(int arg)

Configuration

<behavior name="ReceivingServiceBehavior">
    <!-- Other behaviors -->
    <serviceAuthorization impersonateCallerForAllOperations="true" />
</behavior>

When I try to connect and run my query I get the following:

Exception - System.IO.FileLoadException: Could not load file or
assembly 'System.Transactions, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089' or one of its dependencies. Either a
required impersonation level was not provided, or the provided
impersonation level is invalid. (Exception from HRESULT: 0x80070542)

File name: 'System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' ---> System.Runtime.InteropServices.COMException (0x80070542): Either a required impersonation level was not provided, or the provided impersonation level is invalid. (Exception from HRESULT: 0x80070542)
   at System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionUser user)
   at System.Data.Linq.SqlClient.SqlProvider.get_IsSqlCe()
   at System.Data.Linq.SqlClient.SqlProvider.InitializeProviderMode()
   at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
   at System.Data.Linq.DataQuery`1.System.Collections.Generic.IEnumerable.GetEnumerator()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Fourth.GHS.MessageRelay.RegistrationDBStorage.FindRegistration(SystemKey key)

Best Answer

Does your WCF client set the required "allowed impersonation level":

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>

        <!-- .... -->

        <behaviors>
           <endpointBehaviors>
              <behavior name="ImpersonationBehavior">
                 <clientCredentials>
                      <windows allowedImpersonationLevel="Impersonation" />
                 </clientCredentials>
              </behavior>
           </endpointBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>

By default this is set to Identification if nothing is specified explicitly. Check out this blog post for more info.

Related Topic