C# IIS 6.0上承载的WCF服务中的SecurityNegotiationException

C# IIS 6.0上承载的WCF服务中的SecurityNegotiationException,c#,.net,asp.net,wcf,web-config,C#,.net,Asp.net,Wcf,Web Config,我在IIS上托管了WCF服务。配置文件如下所示 <?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 V

我在IIS上托管了WCF服务。配置文件如下所示

<?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>

当我试图从客户端应用程序访问服务时,我得到了

证券谈判例外

详情如下:

无法打开安全通道 因为安全谈判 远程终结点已失败。今年五月 由于缺席或错误 中指定的EndpointIdentity 用于创建 频道请核实 指定或暗示的端点标识 正确地使用端点地址 标识远程终结点


如果我在ASP.NET开发服务器上托管该服务,它工作正常,但如果我在IIS上托管,则会发生上述错误。

检查是否有帮助。

创建新的测试应用程序,并将服务引用添加到IIS上托管的服务。 完成后,检查client app.config中的安全配置。然后,只需找出与原始客户端应用程序的差异


通常,当客户端和服务器之间的安全配置不同时,会引发此异常。WCF无法找到满足双方要求的通用安全策略集。

我注意到客户端代码中的clientCredentialType设置为“windows”。这将使用内置的Windows身份验证,因此可能运行客户端的用户在服务主机上没有适当的权限


话虽如此,我不确定它应该是什么,但它可能是一条值得探索的路径。

如果您的IIS是Active Directory域的成员,它必须具有有效的服务主体名称(SPN)(请参阅:)

您还必须更改客户端端点配置以指定预期的SPN

尝试对您的IIS托管服务运行
svcutil
,以生成新的客户端配置文件

示例:
svcutil.exe


然后找到生成端点的
部分。它应该包含一个
节点。现在使用此配置文件尝试您的客户端。

我认为您应该从客户端和服务器配置中删除
节点。这可能已经让它起作用了。如果这还不起作用,我会将
wsHttpBinding
从客户端复制到服务器配置。可能还缺少一些东西,但你应该更靠近些


然而还有另一个问题:我认为你应该清楚你想要什么样的安全。你把不同的设置搞混了(例如,您配置了安全模式
传输
,但您也有
消息
安全设置。我想这有助于我为WCF设置Kerberos。所有操作都是在代码中完成的,但您可以很容易地猜到配置的样子。

绑定部分是在客户端定义的,而不是在服务器上定义的

客户机上定义的内容与服务器上使用的默认值之间的差异可能会导致此问题


另一个可能的问题是部分信任问题。WCF中的安全性要求对全部功能具有完全信任。没有这一点,它只支持功能的一个子集,请参阅。

我阅读了这篇文章,但没有得到我需要做的具体操作:(.@Ram:您的iis版本是什么?在iis中托管服务后,您从浏览器调用服务时是否出现任何错误?不,我没有收到任何错误。我从浏览器浏览服务。您的iis是否安装在与客户端相同的计算机上?@Ladislav Mrnka:它安装在同一台计算机上。我还尝试在其他iis上托管服务,结果是相同。:(.您的用户权限是什么?是管理员吗?您在“目录安全”选项卡->身份验证方法中设置了什么用户?您是指新的控制台应用程序吗?当前客户端应用程序是我为测试此服务而创建的winform应用程序。