.net 为什么当我在 WCF 服务中模拟时,当我尝试运行 LINQ to SQL 查询时,我的服务无法加载 System.Transactions?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/277881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why, when I impersonate within a WCF service, can my service not load System.Transactions when I try to run a LINQ to SQL query?
提问by Simon
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:
我有一个 WCF 服务,托管在 IIS 7.0 中,需要运行数据库查询。为了获得正确的权限,我在服务中模拟如下:
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)
采纳答案by Kwal
If you want the SQL queries to be executed as the impersonated identity, you may actually need to enable delegation to your SQL server. Check out this article for more info:
如果您希望 SQL 查询作为模拟身份执行,您实际上可能需要启用对 SQL 服务器的委派。查看这篇文章了解更多信息:
回答by huseyint
Does your WCF client set the required "allowed impersonation level":
您的 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>
By default this is set to Identificationif nothing is specified explicitly. Check out this blog postfor more info.
默认情况下,如果没有明确指定,则设置为标识。查看此博客文章了解更多信息。
回答by Kwal
thank you guys, I solved it by reading the XML under the declaration of:
谢谢你们,我通过阅读声明下的XML解决了这个问题:
[OperationBehavior(Impersonation:=ImpersonationOption.Required)]
it worked only when I read the XML directly from the WCFService Class.
它仅在我直接从 WCFService 类读取 XML 时才起作用。
回答by Kwal
Thank you huseyint. I've been fighting this one for the past day and a half. Here's some stuff that would have saved me a ton of time. So hopefully it will save someone else some time. I was having problems with the SQLConnection and impersonation throwing a registry access is denied using transport security. I tried even using transportwithmessagecredential. Inside of procmon I was getting "Bad Impersonation". My config is IIS 7, virtual dir only has windows authentication enabled and I disabled kernel mode authentication. Basic settings I set it to use pass through authentication.
谢谢你。在过去的一天半中,我一直在与这个斗争。这里有一些可以为我节省大量时间的东西。所以希望它会为其他人节省一些时间。我遇到了 SQLConnection 问题,并且使用传输安全性拒绝了模拟抛出注册表访问。我什至尝试使用transportwithmessagecredential。在 procmon 里面,我收到了“Bad Impersonation”。我的配置是 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>
and the client
和客户
<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>
回答by Abdelrahman ELGAMAL
This one solved my problem.
这个解决了我的问题。
Right click on Visual studio (whichever version you use) Properties Select compatibility tab Fill the checkbox which says "Run this program as administrator" Open the project from the file location Run the application
右键单击 Visual Studio(无论您使用哪个版本) 属性 选择兼容性选项卡 填写“以管理员身份运行此程序”复选框 从文件位置打开项目 运行应用程序
回答by Simon
Having played around with this some more, the easiest solution for IIS hosted services is to run your Application Pool with the identity of a domain user that has the requisite permissions. There are probably issues with this in terms of security but for our purposes it's good enough. We can restrict the permissions given to that user but everything works without having to get into Kerberos, impersonation, delegation and the mysteries of AD.
对此进行了更多研究后,IIS 托管服务的最简单解决方案是使用具有必要权限的域用户的身份运行应用程序池。这在安全性方面可能存在问题,但就我们的目的而言,这已经足够了。我们可以限制授予该用户的权限,但一切都可以正常工作,而无需进入 Kerberos、模拟、委托和 AD 的奥秘。
回答by Marc Gravell
Hmmm... I don't know. However, you could force the dll to load early on. Since you are using IIS, this would presumably be in your global.asax - something like creating and throwing away a TransactionScope should do the job...
嗯……我不知道。但是,您可以强制提前加载 dll。由于您使用的是 IIS,这大概在您的 global.asax 中 - 像创建和丢弃 TransactionScope 这样的东西应该可以完成这项工作......

