简体   繁体   English

WCF中的OneWay操作是否与ClientCertificateMappingAuthorization兼容?

[英]Are OneWay Operations in WCF compatible with ClientCertificateMappingAuthorization?

I made a WCF with one void method and deployed it on IIS; 我使用一种void方法制作了WCF,并将其部署在IIS上。 it works fine (the service response is code 202) until I put it under SSL with Client Certificate Authentication: in this case the code behind the operation is not executed and the server response is 200. No Exception seems to be raised (No Failed Request is traced, no Errors on Events Viewer) but I can't get the execution of called method 它将正常工作(服务响应为代码202),直到我将其置于带有客户端证书身份验证的SSL下:在这种情况下,该操作背后的代码未执行且服务器响应为200。似乎未引发异常(无失败请求)被跟踪,事件查看器上没有错误),但是我无法执行被调用方法

Here's the WCF implementation and configuration: 这是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>

The client code and its 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>        

On server logs I can see this call: 在服务器日志上,我可以看到此调用:

2019-01-11 14:45:01 W3SVC1 10.0.0.4 POST /WcfTestService - 443 SDI_user 130.0.139.146 - 200 0 0 187

where SDI_user is the name of the user specified in the section of manyToOneMapping in IIS as shown in picture: ( https://drive.google.com/open?id=1gGN6HrIDC9u160FuWx6MBwgi7MW7ppRS ) 其中SDI_user是IIS中manyToOneMapping部分中指定的用户名,如图所示:( https://drive.google.com/open?id=1gGN6HrIDC9u160FuWx6MBwgi7MW7ppRS

the best thing to do is to add WCF tracing both on the server and in the client side https://docs.microsoft.com/en-us/dotnet/framework/wcf/diagnostics/tracing/configuring-tracing this should give you details of what is happening. 最好的办法是在服务器和客户端上都添加WCF跟踪https://docs.microsoft.com/zh-cn/dotnet/framework/wcf/diagnostics/tracing/configuring-tracing这应该给您发生的事情的详细信息。 If needed post here the svclog file 如果需要,请在此处发布svclog文件

我检查了您的配置,并想知道为什么不以标准方式使用客户端证书-不了解安全模式-传输同时进行传输和邮件安全我建议您遵循以下示例: https : //docs.microsoft.com/ zh-cn / dotnet / framework / wcf / feature-details / transport-security-with-certificate-authentication使用wsHttpBinding请在此处进行比较: https : //www.codeproject.com/Articles/36396/Difference-between-BasicHttpBinding-和-WsHttpBind

thanks to everyone (expecially oshvartz); 感谢所有人(尤其是oshvartz); I just found the cause: in the client code I had to specify the endpoint address complete of .svc file. 我只是找到了原因:在客户端代码中,我必须指定.svc文件的完整端点地址。 Here's the full code and configuration. 这是完整的代码和配置。

WCF implementation and configuration: 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: 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>

Client implementation: 客户实施:

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();
        }

Client configuration: 客户端配置:

<?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>    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM