2011-01-10 193 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