我用一种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)
答案 0 :(得分:0)
最好的办法是在服务器端和客户端都添加WCF跟踪 https://docs.microsoft.com/en-us/dotnet/framework/wcf/diagnostics/tracing/configuring-tracing 这应该为您提供正在发生的事情的详细信息。如果需要,请在此处发布svclog文件
答案 1 :(得分:0)
我查看了您的配置,并想知道为什么不以标准方式使用客户端证书-不了解安全模式-传输同时进行传输和邮件安全 我建议您遵循以下示例:https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/transport-security-with-certificate-authentication 使用wsHttpBinding外观进行比较:https://www.codeproject.com/Articles/36396/Difference-between-BasicHttpBinding-and-WsHttpBind
答案 2 :(得分:0)
感谢所有人(尤其是oshvartz);我只是找到了原因:在客户端代码中,我必须指定.svc文件的完整端点地址。这是完整的代码和配置。
WCF的实现和配置:
namespace WcfTestService
{
[ServiceContract]
public interface IWcfTestService
{
[OperationContract(IsOneWay =true)]
[XmlSerializerFormat()]
void OneWay(int value);
}
}
namespace WcfTestService
{
[ServiceBehavior]
public class Service1 : IWcfTestService
{
[OperationBehavior]
public void OneWay(int value)
{
Trace.TraceInformation(DateTime.Now.ToString() + " " + "Oneway method invoked! Parameter= " + value.ToString());
Trace.Flush();
}
}
}
WCF配置:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WcfTestBinding" messageEncoding="Mtom" 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="TransportWithMessageCredential">
<message clientCredentialType="Certificate" />
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="WcfTestService.Service1" behaviorConfiguration="WcfTestBehaviors">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="WcfTestBinding" contract="WcfTestService.IWcfTestService" />
<endpoint contract="IMetadataExchange" binding="mexHttpsBinding" address="mex" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfTestBehaviors">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
<security>
<authentication>
<anonymousAuthentication enabled="true" />
</authentication>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" users="myuser" />
</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-500" />
</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="WCFConsumerTraceListener" type="System.Diagnostics.TextWriterTraceListener"
initializeData="logs\WcfTestService.txt" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
客户端实现:
static void Test1Remoto()
{
EndpointAddress newEP = new EndpointAddress("https://mydomain/WcfTestService/WcfTestService.svc");
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);
myWS.Close();
}
客户端配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IWcfTestService" messageEncoding="Mtom">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://mydomain/WcfTestService/WcfTestService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IWcfTestService"
contract="srvRefTest.IWcfTestService" name="WSHttpBinding_IWcfTestService" />
</client>
</system.serviceModel>
</configuration>