我用一种 void 方法制作了一个 WCF,并将其部署在 IIS 上;它工作正常(服务响应是代码 202),直到我将其置于带有客户端证书身份验证的 SSL 下:在这种情况下,操作背后的代码未执行,服务器响应为 200。似乎没有引发异常(没有失败的请求被跟踪,事件查看器上没有错误)但我无法执行被调用的方法
这是 WCF 的实现和配置:
namespace WcfTestService
{
[ServiceContract]
public interface IWcfTestService
{
[OperationContract(IsOneWay =true)]
void OneWay(int value);
}
[ServiceBehavior]
public class Service1 : IWcfTestService
{
[OperationBehavior]
public void OneWay(int value)
{
Trace.TraceInformation(DateTime.Now.ToString() + " Oneway method invoked!" );
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="WcfTestBinding" messageEncoding="Text" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferPoolSize="50000000" maxReceivedMessageSize="50000000">
<readerQuotas maxDepth="500000000" maxStringContentLength="500000000" maxArrayLength="500000000" maxBytesPerRead="500000000" maxNameTableCharCount="500000000" />
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WcfTestService.Service1" behaviorConfiguration="WcfTestBehaviors">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="WcfTestBinding" contract="WcfTestService.IWcfTestService" />
<endpoint contract="IMetadataExchange" binding="mexHttpsBinding" address="mex" />
</service>
</services>
<protocolMapping>
<add binding="wsHttpBinding" scheme="https" />
</protocolMapping>
<behaviors>
<serviceBehaviors>
<behavior name="WcfTestBehaviors">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="500" maxConcurrentInstances="500" maxConcurrentSessions="500" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
<security>
<authentication>
<anonymousAuthentication enabled="true" />
<iisClientCertificateMappingAuthentication enabled="true">
<oneToOneMappings>
<clear />
</oneToOneMappings>
</iisClientCertificateMappingAuthentication>
</authentication>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" users="" roles="Users" />
</authorization>
</security>
<tracing>
<traceFailedRequests>
<remove path="*" />
<add path="*">
<traceAreas>
<add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,FastCGI" verbosity="Verbose" />
</traceAreas>
<failureDefinitions timeTaken="00:00:00" statusCodes="401.2,202" />
</add>
</traceFailedRequests>
</tracing>
</system.webServer>
<system.diagnostics>
<switches>
<add name="DataMessagesSwitch" value="1" />
<add name="TraceLevelSwitch" value="4" />
</switches>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="WcfTestServiceTraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="logs\WcfTestService.txt" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
客户端代码及其配置:
static bool Test()
{
string certPath = @"C:\myCertName.pfx";
string pwdValue = "myPassword";
bool res = false;
EndpointAddress newEP = new EndpointAddress("https://myservername/WcfTestService");
BasicHttpsBinding newBind = new BasicHttpsBinding();
newBind.Security.Mode = BasicHttpsSecurityMode.Transport;
newBind.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
srvRefTest.WcfTestServiceClient myWS = new srvRefTest.WcfTestServiceClient(newBind,newEP);
System.Net.ServicePointManager.ServerCertificateValidationCallback +=
(se, cert, chain, sslerror) =>
{
return true;
};
X509Certificate2 ccert = new X509Certificate2(certPath, pwdValue);
myWS.ClientCredentials.ClientCertificate.Certificate = ccert;
myWS.OneWay(1);
return res;
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IWcfTestService">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://myservername/WcfTestService/WcfTestService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IWcfTestService"
contract="srvRefTest.IWcfTestService" name="BasicHttpBinding_IWcfTestService" />
</client>
</system.serviceModel>
</configuration>
在服务器日志上,我可以看到这个调用:
2019-01-11 14:45:01 W3SVC1 10.0.0.4 POST /WcfTestService - 443 SDI_user 130.0.139.146 - 200 0 0 187
其中 SDI_user 是在 IIS 中的 manyToOneMapping 部分中指定的用户的名称,如图所示:(https://drive.google.com/open?id=1gGN6HrIDC9u160FuWx6MBwgi7MW7ppRS)