WCF / wsHttpBinding /消息安全 - BadTokenRequest

时间:2017-10-26 02:30:31

标签: c# wcf security message

因此我找到了一个较旧的WCF服务/客户端。添加了一个新的(静态)日志记录系统,实际上现在正在做一些负载测试。

现在得到一些非常烦人的零星问题 - 声称"安全通道无法打开,因为与远程端点的安全协商失败了#34;我注意到我收到一个CommunicationException,其中包含Sender的故障名称和BadContextToken的子代码。

奇怪的是,我会得到2-4个正确答案,然后是一系列这些例外,然后再次开始得到好的答案。

这是我第一次真正涉足WCF,到目前为止还不喜欢它。)

服务web.config:

<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <security mode="Message">
        <message clientCredentialType="UserName" />
      </security>
    </wsHttpBinding>
  </bindings>
  <services>
    <service behaviorConfiguration="ServiceBehavior" name="MyNamespace.MyService">
      <endpoint address="" binding="wsHttpBinding" contract="MyNamespace.IMyService" bindingConfiguration="wsMessage">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="ServiceBehavior">
        <serviceMetadata httpGetEnabled="false" />
        <serviceCredentials>
          <serviceCertificate findValue="MyValue" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyNamespace.UserNamePassValidator, MyNamespace" />
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

在客户端,客户端实例化为:

var binding = new WSHttpBinding();
binding.Name = "WSHttpBinding_IMyService";
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

var client = new MyService(binding, "http://myserver:8080/myapp/service.svc");

var endpointIdentity = new DnsEndpointIdentity("MyValue"); // Match the certificate name used by the server

client.Endpoint.Address = new EndpointAddress(new Uri("http://myserver:8080/myapp/service.svc"), endpointIdentity, client.Endpoint.Address.Headers);

var creds = client.ClientCredentials;

creds.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
creds.UserName.UserName = "myuser";
creds.UserName.Password = "mypassword";

string retVal = client.SendRequest(); // SendRequest == one of the methods on my IMyService, returns a string.  This is also where I sporadically see my error when load testing.

我很感激能帮助我完成此WCF设置的任何指示!

1 个答案:

答案 0 :(得分:0)

这些可能是对web.config的有用补充:

<behaviors> 
    <serviceBehaviors> 
        <behavior name="CalculatorServiceBehavior">
            <serviceDebug includeExceptionDetailInFaults="False" /> 
            <serviceMetadata httpGetEnabled="True"/> 
            <serviceThrottling maxConcurrentCalls="20" maxConcurrentInstances="100"/> 
        </behavior>
     </serviceBehaviors>
</behaviors>

<binding name="basicHttp" allowCookies="true" maxReceivedMessageSize="1048576" maxBufferSize="1048576" maxBufferPoolSize="1048576">
    <readerQuotas maxDepth="32" maxArrayLength="1048576" maxStringContentLength="1048576"/>
</binding>

通常这种“随机”行为可能取决于:

  1. 超时(可能不是你的情况,因为你会得到一个不同的例外)
  2. 连接太多:如果客户端打开了太多连接(并“忘记”关闭它们),您将超出默认的允许最大值(取决于上下文,它可能是10个连接)。 如果您更改了web.config,正在修改maxConcurrentCallsmaxConcurrentInstances
  3. ,则可以对此采取相应措施
  4. 也许这些错误不是随机的,而是某些消息所特有的;如果是这样,那可能是由于它的大小(即它太大):再次,改变你的web.config设置maxReceivedMessageSizemaxBufferSizemaxBufferPoolSizereaderQuotas
  5. 当然,如果您开启WCF tracing,您将获得更多信息。