2010-11-03 52 views
1

我有一個調用WCF服務的網頁,該服務使用集成安全性進行SQL數據庫調用。我收到一條錯誤消息:「用戶'CorpDomain \ ServerName01 $'」登錄失敗。我希望它能夠在用戶的AD憑據(在Intranet中工作)下執行所有層,即:「CorpDomain \ Albert」。ASP.NET調用WCF服務時的身份驗證/冒充問題

在服務器(Win 2008/IIS 7)上,我爲Web客戶端和WCF服務啓用了Windows身份驗證,並且其他所有功能都關閉(包括匿名)。

這裏是我的客戶的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> 

客戶端

請求。 ServerVariables [「AUTH_USER」]。ToString()=「CorpDomain \ Alb ERT」

Page.User.Identity.Name = 「CORPDOMAIN \阿爾伯特」

System.Threading.Thread.CurrentPrincipal.Identity.Name = 「CORPDOMAIN \阿爾伯特」

System.Security.Principal。 。WindowsIdentity.GetCurrent()名稱= 「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(); 
} 

注: 我得到的錯誤是:ERROR :用戶'CorpDomain \ ServerName01 $'登錄失敗。

任何想法我做錯了什麼?

回答

0

您還需要在WCF服務級別啓用模擬。

MSDN page包含所有細節。

+0

嘗試前一陣子在頁面上列出的建議。我重新編輯了我的帖子以包含我的大部分代碼。 – Dakhath 2010-11-03 16:22:18

+0

我已經能夠通過更改客戶端web.config只能通過更改客戶端連接的sql連接: 並啓用匿名身份驗證。這是我能做的最好的,但仍然希望有一個有效的解決方案。 – Dakhath 2010-11-03 17:31:28

0

我不知道這是否會幫助任何人,但我有這個問題。問題是由於我的服務在IIS中使用的應用程序池的標識設置。如果你在那裏設置適當的身份,你應該很好。在我的情況下,默認設置爲NT Authority \ Network Service。

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>