c# - 获取 403 禁止错误。客户端身份验证方案 'Anonymous' 禁止 HTTP 请求

标签 c# wcf

我遇到的这个问题并没有发生在所有访问我们服务的客户身上,但一致的是,当错误确实发生时,它发生在少数客户的同一个服务调用上。

以下是异常的详细信息:

System.ServiceModel.Security.MessageSecurityException The HTTP request was forbidden with client authentication scheme 'Anonymous'. System.ServiceModel.Security.MessageSecurityException: The HTTP request was forbidden with client authentication scheme 'Anonymous'. > ---> System.Net.WebException: The remote server returned an error: (403) Forbidden. at System.Net.HttpWebRequest.GetResponse() at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout) --- End of inner exception stack trace --- Server stack trace: at System.ServiceModel.Security.IssuanceTokenProviderBase1.DoNegotiation(TimeSpan timeout) at System.ServiceModel.Security.SspiNegotiationTokenProvider.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.TlsnegoTokenProvider.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.CommunicationObjectSecurityTokenProvider.Open(TimeSpan timeout) at System.ServiceModel.Security.SecurityUtils.OpenTokenProviderIfRequired(SecurityTokenProvider tokenProvider, TimeSpan timeout) at System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelFactory1.ClientSecurityChannel1.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout) at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout) at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout) at System.ServiceModel.Security.SecuritySessionClientSettings1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade) at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at > Proxy.FileTransferService.IFileTransferService.EstablishProxy(DownloadRequest request) at Proxy.FileTransferService.FileTransferServiceClient. Proxy.FileTransferService.IFileTransferService.EstablishProxy(DownloadRequest request) at NormalFileTransferServiceClient.Download(Int32 packageId, IStreamWriter downloader, Archiver archiver) at LoggingFileTransferServiceClient.Download(Int32 packageId, ISt

客户端正在抛出该异常。

IFileTransferService 的客户端代理配置为:

<binding name="WSHttpBinding_IFileTransferService" 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="Mtom"
  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="UserName" negotiateServiceCredential="true"
      algorithmSuite="Default" establishSecurityContext="true" />
  </security>
</binding>

  <endpoint address="http://[hostname]/FileTransferService.svc/FileTransfer"
    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IFileTransferService"
    contract="Proxy.FileTransferService.IFileTransferService"
    name="WSHttpBinding_IFileTransferService">
    <identity>
      <certificate encodedValue="a long string"/>
    </identity>
  </endpoint>

服务配置为

<service behaviorConfiguration="ServiceBehavior" 
    name="Services.FileTransferService">
        <endpoint name="WSHttpBinding_IFileTransferService" 
       binding="wsHttpBinding" 
       bindingConfiguration="MtomWSHttpBinding" 
       contract="Services.IFileTransferService" 
       address="/FileTransfer"/>
        <endpoint binding="basicHttpBinding" 
       bindingConfiguration="FileTransferServicesBinding" 
       contract="Services.IFileTransferService"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://[hostname]/FileTransferService.svc"/>
          </baseAddresses>
        </host>
</service>

<binding name="wsHttpBinding" 
         maxReceivedMessageSize="2147483647" 
         receiveTimeout="5" 
         useDefaultWebProxy="false">
      <readerQuotas maxDepth="2147483647" 
             maxStringContentLength="2147483647" 
             maxArrayLength="2147483647" 
             maxBytesPerRead="2147483647" 
             maxNameTableCharCount="2147483647" />
  <security mode="Message">
    <message clientCredentialType="UserName" />
  </security>
</binding>

<basicHttpBinding>
    <binding name="FileTransferServicesBinding" 
           maxReceivedMessageSize="10067108864" 
           messageEncoding="Mtom" 
           transferMode="Streamed" 
           useDefaultWebProxy="false">
      <security mode="None">
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </basicHttpBinding>

注意:一些客户端正在使用 basicHttpBinding(如果我正确设置了所有内容)。在可能尚未完全分发的客户端的更高版本中(这就是我必须支持 2 版本的原因),我将代理更改为使用 wsHttpBinding 端点。我想知道我收到的这个错误是否特定于 basicHttp,如果是这样,也许我没有正确设置这些配置。我假设收到此 403 错误的客户端正在使用 wsHttpBinding。

这是服务的代码:

public RemoteBinaryInfo EstablishProxy(DownloadRequest request)
{
    int packageId = request.PackageId;

    System.IO.MemoryStream stream = new System.IO.MemoryStream(packageRepository.GetPackageBinary(packageId));

    DisposeStreamWhenOperationIsComplete(stream, OperationContext.Current);

    RemoteBinaryInfo result = new RemoteBinaryInfo();
    result.Length = stream.Length;
    result.MemoryByteStream = stream;
    return result;

}

private static void DisposeStreamWhenOperationIsComplete(System.IO.MemoryStream stream, OperationContext clientContext)
{
    clientContext.OperationCompleted += new EventHandler(delegate(object sender, EventArgs args)
    {
        if (stream != null)
            stream.Dispose();
    });
}

有谁知道摆脱这个异常是否在我的控制范围内?我可以对客户端或服务配置文件进行任何配置更改吗?

如果您需要我提供更多信息,请告诉我。

最佳答案

在我的例子中,这个错误来 self 们组织的 HTTP 代理服务器。从以下位置找到它: MessageSecurityException.InnerException.Response.Headers:

{Mime 版本:1.0
X-Squid-错误:ERR_ACCESS_DENIED 0
X-Cache:来自 <
的 MISS X-Cache-Lookup:NONE 来自
代理连接:关闭
内容长度:2165
内容类型:文本/html
日期:2012 年 4 月 25 日星期三 10:55:39 GMT
服务器:squid/3.0.STABLE25
通过:1.0 <代理服务器地址> (squid/3.0.STABLE25)
}

在我的案例中,文件传输方法也发生了这种情况,该方法在大小为 16384 的 byte 数组中传输文件 block 。在将大小减小到 10000 时,错误得到解决。这意味着代理服务器设置了某种大小限制。

在可以直接访问 Internet 的机器上,文件传输方法从未因此错误而失败,即使数组大小 > 16384。

因为只有您的一些客户端面临这个问题,可能他们在防火墙/代理服务器后面,而实际上是阻止访问并返回此错误的服务器?

关于c# - 获取 403 禁止错误。客户端身份验证方案 'Anonymous' 禁止 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7826793/

相关文章:

c# - 安装 Roslyn 会对我的 VS 安装产生什么影响

c# - 处理这两个依赖于另一个的异步方法的最佳方法是什么?

c# - 将 SQLServer 的 DateTime 转换为 MySQL

WCF将异常传递给客户端

wcf - 已超过最大名称表字符数配额 (16384)

c# - 更改枚举菜单名称格式 [C#]

c# - 将跟踪 id/span id 设置为实际的关联 ID,以使用 OpenTelemetry for c# 跟踪请求

mysql - 使用 MySql.Data.MySqlClient 时出现 WCF 服务错误

jquery - 使用 JQuery 将对象传递给 WCF 服务

c# - 从 WinRT 中执行 WS-Discovery