Почему, когда я исполняю роль внутри службы WCF, моя служба не может загрузить System.Transaction, когда я пытаюсь выполнить запрос LINQ to SQL? - PullRequest
8 голосов
/ 10 ноября 2008

У меня есть служба WCF, размещенная в IIS 7.0, которая должна выполнять запросы к базе данных. Чтобы получить необходимые разрешения для этого, я подражаю в службе следующим образом:

код

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

Конфигурация

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

Когда я пытаюсь подключиться и выполнить свой запрос, я получаю следующее:

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)

Ответы [ 7 ]

6 голосов
/ 26 ноября 2008

Устанавливает ли ваш клиент WCF необходимый «разрешенный уровень олицетворения»:

<?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>

По умолчанию это значение равно Идентификация , если ничего не указано явно. Проверьте это сообщение в блоге для получения дополнительной информации.

3 голосов
/ 10 ноября 2008

Если вы хотите, чтобы SQL-запросы выполнялись как олицетворенная личность, вам может потребоваться включить делегирование на ваш SQL-сервер. Проверьте эту статью для получения дополнительной информации:

http://msdn.microsoft.com/en-us/library/ms730088.aspx

1 голос
/ 08 января 2009

спасибо, ребята, Я решил это, прочитав XML под объявлением:

[OperationBehavior(Impersonation:=ImpersonationOption.Required)]

это работало только когда я читал XML напрямую из класса WCFService.

0 голосов
/ 30 марта 2015

Это решило мою проблему.

Щелкните правой кнопкой мыши Visual Studio (какую бы версию вы не использовали) свойства Выберите вкладку совместимости Заполните флажок «Запустить эту программу от имени администратора» Откройте проект из местоположения файла Запустите приложение

0 голосов
/ 01 июля 2009

Спасибо, Хусейинт. Я боролся с этим в течение последних полутора дней. Вот кое-что, что сэкономило бы мне кучу времени. Надеюсь, это сэкономит кому-то еще время. У меня были проблемы с SQLConnection, и выдача имитации, запрещающей доступ к реестру с использованием безопасности транспорта Я пытался даже использовать транспорт с сообщением сообщений. Внутри procmon я получал «Плохое олицетворение». Мой конфиг IIS 7, в виртуальном каталоге включена только проверка подлинности Windows, и я отключил проверку подлинности в режиме ядра. Основные настройки Я установил использование сквозной аутентификации.

Service Config -

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
    <services>
      <service behaviorConfiguration="SymitarService.ScheduleServiceBehavior" name="SymitarService.ScheduleService">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsSecure" contract="SymitarService.IScheduleService">
          <identity>
            <dns value="localhost" />            
          </identity>
        </endpoint>
        <endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="wsSecure" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SymitarService.UserDirectoryBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceAuthorization impersonateCallerForAllOperations="true" />
        </behavior>
        <behavior name="SymitarService.ScheduleServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceAuthorization impersonateCallerForAllOperations="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netTcpBinding>
        <binding name="tcpSecure" portSharingEnabled="true" />
      </netTcpBinding>
      <wsHttpBinding>
        <binding name="wsSecure" allowCookies="true">
          <security mode="Transport">
            <transport clientCredentialType="Windows" proxyCredentialType="Windows" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true" />
          </security>
        </binding>
      </wsHttpBinding>
      <mexTcpBinding>
        <binding name="mexSecure" />
      </mexTcpBinding>
    </bindings>
  </system.serviceModel>

и клиент

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_IScheduleService" closeTimeout="01:00:00" openTimeout="01:00:00" receiveTimeout="01:00:00" sendTimeout="01:00:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" useDefaultWebProxy="true" allowCookies="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:20:00" enabled="false" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" proxyCredentialType="Windows" realm="" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="ImpersonationBehavior">
          <clientCredentials>
            <windows allowedImpersonationLevel="Impersonation" allowNtlm="true"/>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <client>
      <endpoint address="https://server:444/SymitarService/ScheduleService.svc" 
                binding="wsHttpBinding" 
                bindingConfiguration="WSHttpBinding_IScheduleService" 
                contract="Symitar.ScheduleService.IScheduleService" 
                name="WSHttpBinding_IScheduleService"
                behaviorConfiguration="ImpersonationBehavior"
                >
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
0 голосов
/ 11 ноября 2008

Поэкспериментировав с этим, самое простое решение для служб, размещенных на IIS, - запустить пул приложений с идентификатором пользователя домена, обладающего необходимыми разрешениями. Вероятно, есть проблемы с этим с точки зрения безопасности, но для наших целей это достаточно хорошо. Мы можем ограничить разрешения, предоставленные этому пользователю, но все работает без необходимости входить в Kerberos, олицетворение, делегирование и тайны AD.

0 голосов
/ 10 ноября 2008

Хммм ... я не знаю. Тем не менее, вы можете заставить dll загружаться раньше. Поскольку вы используете IIS, это, вероятно, будет в вашем global.asax - что-то вроде создания и отбрасывания TransactionScope должно делать эту работу ...

...