我有一个调用WCF服务的网页,该服务使用Integrated Security进行sql数据库调用。我收到一条错误消息,“用户'CorpDomain \ ServerName01 $'登录失败”。我想要它,以便所有层都将在用户的AD凭证(在Intranet中工作)下执行,即:“CorpDomain \ Albert”。
在服务器(Win 2008 / IIS 7)上,我打开了Windows身份验证,并在身份验证下为Web客户端和WCF服务关闭了其他所有内容(包括Anonymous)。
这是我的客户端web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<authentication mode="Windows"/>
<identity impersonate="true"/>
<customErrors mode="Off"/>
</system.web>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IMyService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<!--<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>-->
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://myurladdress/MyServices/Service.svc"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IMyService"
contract="MySvc.IMyService" name="NetTcpBinding_IMyService" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="ClientUserNameBehavior">
<clientCredentials>
<windows allowedImpersonationLevel="Impersonation"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
这是我的WCF服务web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Windows"/>
<identity impersonate="true"/>
</system.web>
<connectionStrings>
<!--DB CONNECTION-->
<add name="myDB" connectionString="Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Carbon;Data Source=mydbname,10600" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.serviceModel>
<services>
<service name="WCFServices.MyService" behaviorConfiguration="MyServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8000/WCFServices/MyService"/>
</baseAddresses>
</host>
<endpoint address="" binding="netTcpBinding" contract="WCFServices.IMyService" bindingConfiguration="tcpWindowsSecurity" bindingNamespace="http://WCFServices.MySvc/"/>
<endpoint address="MEX" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization impersonateCallerForAllOperations="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpWindowsSecurity" maxReceivedMessageSize="524288" maxBufferSize="524288">
<!--<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Windows" protectionLevel="None" />
</security>-->
</binding>
</netTcpBinding>
</bindings>
<!--<serviceHostingEnvironment multipleSiteBindingsEnabled="true" >-->
<serviceHostingEnvironment >
<serviceActivations>
<add relativeAddress="~/MyService.svc" service="WCFServices.MyService"/>
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
在客户端:
Request.ServerVariables [“AUTH_USER”]。ToString()=“CorpDomain \ Albert”
Page.User.Identity.Name =“CorpDomain \ Albert”
System.Threading.Thread.CurrentPrincipal.Identity.Name =“CorpDomain \ Albert”
System.Security.Principal.WindowsIdentity.GetCurrent()。Name =“NT AUTHORITY \ NETWORK SERVICE”
我的客户端代码基本上是:
MySvc.MyServiceClient svc = new MySvc.MyServiceClient();
svc.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
Response.Write(svc.GetServiceHtml());
并在 WCF方面:
ServiceSecurityContext.Current.WindowsIdentity.Name =“NT AUTHORITY \ NETWORK SERVICE”
服务器端代码是:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string GetServcieHtml()
{
string name, link;
StringBuilder html = new StringBuilder();
html.Append(ServiceSecurityContext.Current.WindowsIdentity.Name);
try
{
using (SqlConnection conn = GetDataConnection())
{
conn.Open();
SqlCommand sqlcom = new SqlCommand("dbo.runsomeproc", conn);
sqlcom.CommandType = CommandType.StoredProcedure;
SqlDataReader sqlDataReader = sqlcom.ExecuteReader();
while (sqlDataReader.Read())
{
// ** SOME CODE HERE **
}
conn.Close();
}
}
catch (Exception ex)
{
html.AppendLine("<br><br>ERROR:" + ex.Message + " " + ex.InnerException);
return html.ToString();
}
return html.ToString();
}
注意: 我得到的错误是:错误:用户'CorpDomain \ ServerName01 $'登录失败。
知道我做错了吗?
答案 0 :(得分:0)
您还需要在WCF服务级别启用模拟。
此MSDN page包含所有详细信息。
答案 1 :(得分:0)
我不知道这是否会对任何人有所帮助,但我遇到了这个问题。问题是由于我的服务在IIS中使用的应用程序池的标识设置。如果你在那里设置了适当的身份,你应该是好的。在我的例子中,默认设置为NT Authority \ Network Service。
答案 2 :(得分:0)
另外,如果我错了,请更正我,但在您的客户端web.config中,您有一种行为会将模拟级别设置为“模拟”,但您不会在端点中引用该行为。例如:
<client>
<endpoint address="net.tcp://myurladdress/MyServices/Service.svc"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IMyService"
contract="MySvc.IMyService" name="NetTcpBinding_IMyService" />
</client>
应该是:
<client>
<endpoint address="net.tcp://myurladdress/MyServices/Service.svc"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IMyService"
contract="MySvc.IMyService" name="NetTcpBinding_IMyService"
behaviorConfiguration="ClientUserNameBehavior" />
</client>