2011-01-10 159 views
1

我在IIS上託管了一個WCF服務。配置文件如下。在IIS 6.0上託管的WCF服務中的SecurityNegotiationException

<?xml version="1.0"?> 
<!-- 
    Note: As an alternative to hand editing this file you can use the 
    web admin tool to configure settings for your application. Use 
    the Website->Asp.Net Configuration option in Visual Studio. 
    A full list of settings and comments can be found in 
    machine.config.comments usually located in 
    \Windows\Microsoft.Net\Framework\v2.x\Config 
--> 
<configuration> 


    <configSections> 
     <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> 
     <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> 
      <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/> 
      <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> 
      <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" /> 
      <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" /> 
      <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" /> 
      <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" /> 
      </sectionGroup> 
     </sectionGroup> 
     </sectionGroup> 
    </configSections> 


    <appSettings/> 
    <connectionStrings/> 

    <system.web> 
     <!-- 
      Set compilation debug="true" to insert debugging 
      symbols into the compiled page. Because this 
      affects performance, set this value to true only 
      during development. 
     --> 
     <compilation debug="false"> 

      <assemblies> 
      <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> 
      <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
      </assemblies> 

     </compilation> 
     <!-- 
      The <authentication> section enables configuration 
      of the security authentication mode used by 
      ASP.NET to identify an incoming user. 
     --> 
     <authentication mode="Windows" /> 
     <!-- 
      The <customErrors> section enables configuration 
      of what to do if/when an unhandled error occurs 
      during the execution of a request. Specifically, 
      it enables developers to configure html error pages 
      to be displayed in place of a error stack trace. 

     <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"> 
      <error statusCode="403" redirect="NoAccess.htm" /> 
      <error statusCode="404" redirect="FileNotFound.htm" /> 
     </customErrors> 
     --> 


     <pages> 
     <controls> 
      <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     </controls> 
     </pages> 

     <httpHandlers> 
     <remove verb="*" path="*.asmx"/> 
     <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/> 
     </httpHandlers> 
     <httpModules> 
     <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     </httpModules> 


    </system.web> 

    <system.codedom> 
     <compilers> 
     <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" 
        type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
      <providerOption name="CompilerVersion" value="v3.5"/> 
      <providerOption name="WarnAsError" value="false"/> 
     </compiler> 
     </compilers> 
    </system.codedom> 

    <system.web.extensions> 
     <scripting> 
     <webServices> 
      <!-- 
       Uncomment this section to enable the authentication service. Include 
       requireSSL="true" if appropriate. 

      <authenticationService enabled="true" requireSSL = "true|false"/> 
      --> 
      <!-- 
       Uncomment these lines to enable the profile service, and to choose the 
       profile properties that can be retrieved and modified in ASP.NET AJAX 
       applications. 

      <profileService enabled="true" 
          readAccessProperties="propertyname1,propertyname2" 
          writeAccessProperties="propertyname1,propertyname2" /> 
      --> 
      <!-- 
       Uncomment this section to enable the role service. 

      <roleService enabled="true"/> 
      --> 
     </webServices> 
     <!-- 
     <scriptResourceHandler enableCompression="true" enableCaching="true" /> 
     --> 
     </scripting> 
    </system.web.extensions> 
    <!-- 
     The system.webServer section is required for running ASP.NET AJAX under Internet 
     Information Services 7.0. It is not necessary for previous version of IIS. 
    --> 
    <system.webServer> 
     <validation validateIntegratedModeConfiguration="false"/> 
     <modules> 
     <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     </modules> 
     <handlers> 
     <remove name="WebServiceHandlerFactory-Integrated"/> 
     <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" 
      type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" 
      type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
     </handlers> 
    </system.webServer> 


    <system.serviceModel> 
    <services> 
     <service name="IISTest2.Service1" behaviorConfiguration="IISTest2.Service1Behavior"> 
     <!-- Service Endpoints --> 
     <endpoint address="" binding="wsHttpBinding" contract="IISTest2.IService1"> 
      <!-- 
       Upon deployment, the following identity element should be removed or replaced to reflect the 
       identity under which the deployed service runs. If removed, WCF will infer an appropriate identity 
       automatically. 
      --> 
      <identity> 
      <dns value="localhost"/> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="IISTest2.Service1Behavior"> 
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> 
      <serviceMetadata httpGetEnabled="true"/> 
      <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 
</configuration> 

客戶端配置文件如下

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
     <bindings> 
      <wsHttpBinding> 
       <binding name="WSHttpBinding_IService1" closeTimeout="00:01:00" 
        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
        bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
        maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" 
        allowCookies="false"> 
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <reliableSession ordered="true" inactivityTimeout="00:10:00" 
         enabled="false" /> 
        <security mode="Message"> 
         <transport clientCredentialType="Windows" proxyCredentialType="None" 
          realm="" /> 
         <message clientCredentialType="Windows" negotiateServiceCredential="true" 
          algorithmSuite="Default" establishSecurityContext="true" /> 
        </security> 
       </binding> 
      </wsHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="http://yyy.zzz.xxx.net/IISTest2/Service1.svc" 
       binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" 
       contract="ServTest.IService1" name="WSHttpBinding_IService1"> 
       <identity> 
        <dns value="localhost" /> 
       </identity> 
      </endpoint> 
     </client> 
    </system.serviceModel> 
</configuration> 

當我試圖從客戶端應用程序訪問該服務,我得到了

SecurityNegotiationException

和細節

安全通道無法打開 ,因爲與 遠程端點的安全協商失敗。這可能是 是由於缺少或不正確 指定的EndpointIdentity中的 EndpointAddress用於創建 通道。請確認 EndpointAddress正確指定或暗示 的EndpointIdentity 標識遠程端點。

如果我在ASP.NET開發服務器上託管服務,它運行良好,但是如果我在IIS上託管,則會出現上述錯誤。

+0

您的IIS與客戶端安裝在同一臺計算機上嗎? – 2011-01-10 08:42:50

+0

@Ladislav Mrnka:它安裝在同一臺機器上。我也嘗試在另一個IIS上託管服務,結果是一樣的。 :(。 – Ram 2011-01-10 09:14:29

+0

你的用戶權限是什麼?是管理員?你在目錄安全選項卡 - >身份驗證方法中設置了什麼用戶? – Rev 2011-01-17 14:18:14

回答

0

創建一個新的測試應用程序,並將服務引用添加到託管在IIS上的服務。 完成後,檢查客戶端app.config中的安全配置。然後,這只是一個發現與原來的客戶端應用程序的差異的問題。

通常,當客戶端和服務器之間的安全配置不同時,會引發此異常,WCF無法找到滿足雙方的一組通用安全策略。

1

我注意到客戶端代碼中的clientCredentialType設置爲「windows」。這使用內置的Windows身份驗證,所以也許客戶端運行的用戶在服務主機上沒有適當的權限。

話雖如此,我不知道它應該是什麼,但它可能是一個值得探索的道路。

0

如果你的IIS是Active Directory域的成員,它必須有一個有效的服務主體名稱(SPN)(見:Setspn on Technet

您還必須更改客戶端的端點配置以指定預期的SPN。

嘗試運行svcutil針對您的IIS託管服務生成新的客戶端配置文件。

例:svcutil.exe http://yyy.zzz.xxx.net/IISTest2/Service1.svc

然後發現所生成的端點的<identity>部分。它應該包含一個<servicePrincipalName>節點。現在用這個配置文件試試你的客戶端。

1

我想你應該從客戶端和服務器配置中刪除<identity>節點。這可能已經使其工作。如果這還不行,我會將wsHttpBinding從客戶端複製到服務器配置。仍然可能會有一些缺失,但你應該更近一些。

然而,還有另一個問題:我認爲你應該清楚你想要什麼樣的安全。你有很多不同的設置(例如,你配置了安全模式Transport,但你也有Message安全設置。我認爲this幫助我爲WCF設置Kerberos。一切都在代碼中完成,但你可以很容易猜到配置會是什麼樣子。

0

的綁定部分是在客戶端上定義,而不是在服務器上。

之間是什麼在客戶端上定義,並在服務器上使用默認設置可能會導致問題的差異。

這可能是另一件事是部分信任問題。WCF中的安全性需要完全信任完整的功能。如果沒有它,它只支持該功能的一個子集,請參閱Partial Trust Feature Compatibility