【问题标题】:WCFTestClient The HTTP request is unauthorized with client authentication scheme 'Anonymous'WCFTestClient HTTP 请求未经授权,客户端身份验证方案“匿名”
【发布时间】:2009-06-25 13:46:14
【问题描述】:

我创建了一个 WCF 服务并将其部署在服务器上。当我浏览此服务时,它会使用 ?wsdl URL 给我积极的响应。现在我正在尝试通过 WCF 测试客户端测试服务。它显示正确的元数据。但是,当我尝试从服务中调用任何方法时,它会向我显示一个异常...这里是带有堆栈跟踪的错误详细信息..

HTTP 请求未经授权 客户端认证方案 '匿名的'。身份验证标头 从服务器收到的是 '协商,NTLM'。

服务器堆栈跟踪:

在
System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest 请求,HttpWebResponse 响应, WebException 响应异常, HttpChannelFactory 工厂)
HTTP 请求未经客户端授权 身份验证方案“匿名”。这 收到的身份验证标头 服务器是“协商,NTLM”。

服务器堆栈跟踪:

在
System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest 请求,HttpWebResponse 响应, WebException 响应异常, HttpChannelFactory 工厂)

客户端绑定:

<bindings>
    <wsHttpBinding>
        <binding name="WSHttpBinding_IServiceMagicService" 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="None">
                <transport clientCredentialType="Windows" proxyCredentialType="None"
                    realm="" />
                <message clientCredentialType="Windows" negotiateServiceCredential="true"
                    establishSecurityContext="true" />
            </security>
        </binding>
    </wsHttpBinding>
</bindings>

服务器绑定:

<bindings>
  <wsHttpBinding>
    <binding name="WSHttpBinding_SEOService" closeTimeout="00:10:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="true" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="999524288" maxReceivedMessageSize="655360000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="900000" maxArrayLength="900000" maxBytesPerRead="900000" maxNameTableCharCount="900000" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
      <security mode="None">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
        <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" />
      </security>
    </binding>
    <binding name="WSHttpServiceMagicBinding" closeTimeout="00:10:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="true" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="999524288" maxReceivedMessageSize="655360000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="900000" maxArrayLength="900000" maxBytesPerRead="900000" maxNameTableCharCount="900000"/>
      <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
      <security mode="None">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
        <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

客户的客户部分:

<client>
    <endpoint address="http://hydwebd02.solutions.com/GeoService.Saveology.com/ServiceMagicService.svc"
        binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServiceMagicService"
        contract="IServiceMagicService" name="WSHttpBinding_IServiceMagicService" />
</client>

服务器的服务部分:

<services>
    <service behaviorConfiguration="GeoService.Saveology.com.CityStateServiceProviderBehavior"
    name="GeoService.Saveology.com.CityStateServiceProvider">
    <endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_SEOService"
        contract="SEO.Common.ServiceContract.ICityStateService" />
    <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
        contract="IMetadataExchange" />
    </service>
    <service behaviorConfiguration="GeoService.Saveology.com.ServiceMagicServiceProviderBehavior"
    name="GeoService.Saveology.com.ServiceMagicServiceProvider">
    <endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpServiceMagicBinding" 
        contract="SEO.Common.ServiceContract.IServiceMagicService">
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" contract="IMetadataExchange" />
    </service>
</services>

【问题讨论】:

  • 当您使用真实客户端调用这些方法时会发生什么?
  • 好的,谢谢 - 但您还需要发布服务器的 部分和客户端的 部分,以便我们了解这些端点的设置方式以及您的情况打电话给他们......
  • 使用真正的客户端,它不会出现任何问题。
  • 我已经发布了客户端的 部分和服务器的 部分。
  • 这是 .Net 世界的征兆,您对同一个问题有如此多(有效)不同的答案,而没有一个解释您要更改哪些参数以及为什么要更改的答案。有人知道他/她在做什么吗?

标签: wcf ntlm anonymous wcftestclient negotiate


【解决方案1】:

我无法控制我调用的服务的安全配置,但遇到了同样的错误。我能够按如下方式修复我的客户。

  1. 在配置中,设置安全模式:

    <security mode="TransportCredentialOnly">
      <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
      <message clientCredentialType="UserName" algorithmSuite="Default" />
    </security>
    
  2. 在代码中,将代理类设置为允许模拟(我添加了对名为 customer 的服务的引用):

    Customer_PortClient proxy = new Customer_PortClient();
    proxy.ClientCredentials.Windows.AllowedImpersonationLevel =    
             System.Security.Principal.TokenImpersonationLevel.Impersonation;
    

【讨论】:

  • 如果您以编程方式执行此操作,请确保使用 Dim 绑定 As New System.ServiceModel.BasicHttpBinding() 而不是 Dim 绑定 As New System.ServiceModel.WSHttpBinding()
  • 我真的不知道 Customer_PortClient 是什么,但是设置安全模式帮助了我。
  • 当使用&lt;security mode="TransportCredentialOnly"&gt; 时,您似乎不需要包括消息安全配置; SOAP 消息以未加密的纯文本形式发送。 &lt;message&gt; 标签似乎被忽略了,所以它不会造成任何伤害,只是不需要它。来源:msdn.microsoft.com/en-us/library/ff648505.aspx
  • “配置”在哪里?我是个新手。编辑:nvmd 从这里弄明白了:docs.microsoft.com/en-us/dotnet/framework/wcf/…
【解决方案2】:

我也有类似的问题,你试过了吗:

proxy.ClientCredentials.Windows.AllowedImpersonationLevel =   
          System.Security.Principal.TokenImpersonationLevel.Impersonation;

【讨论】:

    【解决方案3】:

    我发现的此错误的另一种可能解决方案。可能没有回答 OP 的确切问题,但可能会帮助其他偶然发现此错误消息的人。

    我正在使用 WebHttpBinding 在代码中创建我的客户端,以便复制以下行:

    <security mode="TransportCredentialOnly">
      <transport clientCredentialType="Windows" proxyCredentialType="Windows" />
    </security>
    

    我必须这样做:

    var binding = new WebHttpBinding(WebHttpSecurityMode.TransportCredentialOnly);
                    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
                    binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Windows;
    

    以及设置proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

    【讨论】:

      【解决方案4】:

      我看到这还没有回答,这是一个准确的报价from here:

      WSHttpBinding 将尝试在 SSP 层执行内部协商。为了成功,您需要在 IIS 中为 VDir 允许匿名。然后默认情况下,WCF 将从 SPNEGO 执行窗口凭据。在 IIS 层允许匿名是不允许任何人进入,它是在遵循 WCF 堆栈。

      我通过以下方式找到了这个:http://fczaja.blogspot.com/2009/10/http-request-is-unauthorized-with.html

      谷歌搜索后:http://www.google.tt/#hl=en&source=hp&q=+The+HTTP+request+is+unauthorized+with+client+authentication+scheme+%27Anonymous

      【讨论】:

      • 嗨@Irwin,感谢您的回答。您能否向审核员提供更“官方”的来源,例如微软制作的原始文档,以便我证明这一点?多谢!!马塞洛
      【解决方案5】:

      我遇到了类似的问题,并尝试了上面建议的所有方法。然后我尝试将 clientCreditialType 更改为 Basic,一切正常。

      <basicHttpBinding>
          <binding name="BINDINGNAMEGOESHERE" >
            <security mode="TransportCredentialOnly">
              <transport clientCredentialType="Basic"></transport>
            </security>
          </binding>
        </basicHttpBinding>
      

      【讨论】:

        【解决方案6】:

        这是我必须做的才能让它工作。这意味着:

        1. 自定义 UserNamePasswordValidator(无需 Windows 帐户、SQLServer 或 ActiveDirectory - 您的 UserNamePasswordValidator 可以硬编码用户名和密码,或者从文本文件、MySQL 或其他文件中读取)。
        2. https
        3. IIS7
        4. .net 4.0

        我的网站是通过 DotNetPanel 管理的。它有 3 个虚拟目录的安全选项:

        1. 允许匿名访问
        2. 启用基本身份验证
        3. 启用集成 Windows 身份验证

        只需要“允许匿名访问”(尽管这本身还不够)。

        设置

        proxy.ClientCredentials.Windows.AllowedImpersonationLevel =  System.Security.Principal.TokenImpersonationLevel.Impersonation;
        

        对我的情况没有影响。

        但是,使用此绑定有效:

              <security mode="TransportWithMessageCredential">
                <transport clientCredentialType="Windows" />
                <message clientCredentialType="UserName" />
              </security>        
        

        【讨论】:

          【解决方案7】:

          我今天遇到了同样的错误,在将我们的服务调用外部服务部署到 azure 中的暂存环境之后。本地服务调用外部服务没有错误,但部署后没有。

          最后证明是外部服务有IP验证。 Azure中的新环境有另一个IP,被拒绝了。

          因此,如果您在调用外部服务时遇到此错误

          可能是 IP 限制。

          【讨论】:

          • 我也有同样的问题。请注意,如果 Azure App 服务计划不是专用的,则出站 IP 是虚拟的,将来可能会发生变化。
          【解决方案8】:

          刚刚在开发机器上遇到了这个问题(生产工作正常)。我在 IIS 中修改了我的配置以允许匿名访问,并将我的姓名和密码作为凭据。

          我确信这不是最好的方法,但它适用于测试目的。

          【讨论】:

          • 你能在这里分享相同的代码sn-p吗?
          • 我会努力找的,但是这个帖子是7年前的,不知道能不能找到……
          【解决方案9】:

          我也遇到了这个错误,最后这段代码在 dot net core 3.1

          中对我有用

          首先在命令提示符下安装svcutil:dotnet tool install --global dotnet-svcutil

          然后关闭命令提示符并再次打开它。

          然后在命令提示符下创建Reference.cs:

          dotnet-svcutil http://YourService.com/SayHello.svc

          (需要输入键和用户名和密码)

          将名为 Connected Services 的文件夹添加到项目根目录。

          复制 Reference.cs 文件到 Connected Services 文件夹。

          将这 4 行添加到 Reference.cs 创建 BasicHttpBinding 和设置 MaxBufferSize 的行之后:

          result.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
          result.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
          result.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
          result.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
          

          在您的控制器中使用此服务:

          public async Task<string> Get()
              {
                  try
                  {
                      var client = new EstelamClient();
                      client.ClientCredentials.UserName.UserName = "YourUserName";
                      client.ClientCredentials.UserName.Password = "YourPassword";
                      var res = await client.EmployeeCheckAsync("service parameters");
                      return res.ToString();
                  }
                  catch (Exception ex)
                  {
                      return ex.Message + " ************ stack : " + ex.StackTrace;
                  }
          
              }
          

          不要忘记在 csproj 中安装这些包:

          <PackageReference Include="System.ServiceModel.Duplex" Version="4.6.*" />
          <PackageReference Include="System.ServiceModel.Http" Version="4.6.*" />
          <PackageReference Include="System.ServiceModel.NetTcp" Version="4.6.*" />
          <PackageReference Include="System.ServiceModel.Security" Version="4.6.*" />
          

          【讨论】:

          • result的类型是什么?
          • 这取决于您使用的方法。在我的代码中,EmployeeCheckAsync() 返回一个对象,它位于您通过 dotnet-svcutil 命令创建的 Reference.cs 文件中。
          【解决方案10】:

          尝试在您的客户端中提供用户名和密码,如下所示

          client.ClientCredentials.UserName.UserName = @"Domain\username";
          client.ClientCredentials.UserName.Password = "password";
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-10-27
            • 2019-09-13
            • 1970-01-01
            • 1970-01-01
            • 2011-06-22
            • 1970-01-01
            相关资源
            最近更新 更多