0

I'm consuming a third party J2EE web service that requires sign the request with a certificate, but the web service is responding an unsigned response.

This is the way I'm doing the request:

    public static WcfServiceNamespace.ResponseType GetResponse(X509Certificate2 certificate)
    {
        var request = GetExampleRequest();
        var endPoint = new EndpointAddress($"https://endPoint.url/contoso");
        var binding = GetCustomBinding();

        ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
        using (var client = new WcfServiceNamespace.ServicePortTypeClient(binding, endPoint))
        {
            client.Endpoint.Contract.ProtectionLevel = ProtectionLevel.Sign;
            client.ClientCredentials.ClientCertificate.Certificate = certificate;
            return client.ProcessRequest(request);
        }
    }

    private static Binding GetCustomBinding()
    {
        var c = new CustomBinding();
        var version = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
        var sec = SecurityBindingElement.CreateCertificateOverTransportBindingElement(version);
        sec.EnableUnsecuredResponse = true;
        sec.AllowInsecureTransport = true;
        sec.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
        c.Elements.Add(sec);
        c.Elements.Add(new TextMessageEncodingBindingElement() {MessageVersion = MessageVersion.Soap11});
        c.Elements.Add(new HttpsTransportBindingElement() { RequireClientCertificate = true });
        return c;
    }

The java web service is responding correctly the request without any header:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
       <soapenv:Body>
       <!-- correct response -->
       </soapenv:Body>
    </soapenv:Envelope>

But WCF client is throwing an exception when it tries to process the response:

    System.ServiceModel.Security.MessageSecurityException: 'Cannot find a token authenticator for the 'System.IdentityModel.Tokens.X509SecurityToken' token type. Tokens of that type cannot be accepted according to current security settings.'

I already tried this configuration: WCF - Cannot find a token authenticator for X509SecurityToken But it does not resolve my problem because the header of the response is totally empty as I explained before and the endpoint is using https but has no certificate to trust.

My question is: Is there any way to configure WCF to correctly sign the request but ignore the response security?

Edit: I already tried this questions:

But the answers don't help

Edit: I make it work with WSE3 but I want use a newer technology. If it works in WSE3, Why not in WCF?

rasputino
  • 691
  • 1
  • 8
  • 24
  • Possible duplicate of [WCF - Cannot find a token authenticator for X509SecurityToken](https://stackoverflow.com/questions/38435516/wcf-cannot-find-a-token-authenticator-for-x509securitytoken) – Selim Yildiz Nov 21 '19 at 18:42
  • I already tried it but it does not resolve my problem because the header of the response is totally empty as I explained before and the endpoint is using https but has no certificate to trust. – rasputino Nov 21 '19 at 19:02

1 Answers1

0

Can we use the below tools to generate the SOAP client, with which we can call the service like the below method?
https://learn.microsoft.com/en-us/dotnet/framework/wcf/servicemodel-metadata-utility-tool-svcutil-exe
It is a built-in tool in Visual Studio, and we can generate the client proxy class and the compatible custom binding and security mode configuration by using the SVCUtil command. the client proxy will automatically use the configuration compatible with the server to create the request when instantiating.
Alternatively, we could generate the client proxy by means of the Add service reference menu.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/accessing-services-using-a-wcf-client
I have never called the J2EE web service, please let me know if it helps.

Abraham Qian
  • 7,117
  • 1
  • 8
  • 22
  • It doesn't help, I already know svcutil.exe command. It generates a proxy class and the configuration file in a similar way that "Add service" does, the problem is in the configuration of the service. The svcutil command does not detect the security configuration, it detects a basicHttpBinding and a usual endpoint. – rasputino Nov 22 '19 at 06:59
  • Can the command complete successfully? Like the form below. Svcutil.exe http://abc:8008/service1.svc?singlewsdl /d:D:\ I would like to know the automatically generated configuration. – Abraham Qian Nov 22 '19 at 08:39
  • output.config content: – rasputino Nov 22 '19 at 15:11
  • If we call the service by adding service reference in the Asp.net project, it also will generate the same configuration, is it? What happened if we generate the client proxy, then call the service method, like this. Servicereference1.serviceclient client=new Servicereference1.serviceclient(); Try{ var result=Client.test(); }catch(Exception) { throw; } – Abraham Qian Nov 25 '19 at 05:25
  • Besides, as far as I know, in WCF the basichttpbinding with authenticating the client with a certificate requires that the client provides a certificate to sign the SOAP message. Thereby can we use the ChannelFactory with configuring the below binding type to communicate with the server? – Abraham Qian Nov 25 '19 at 05:42
  • Uri uri = new Uri("https://serviceurl"); BasicHttpBinding binding = new BasicHttpBinding(); binding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential; binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate; ChannelFactory factory = new ChannelFactory(binding, new EndpointAddress(uri)); IService service = factory.CreateChannel(); service.test(); – Abraham Qian Nov 25 '19 at 05:42
  • https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/channel-factory – Abraham Qian Nov 25 '19 at 05:42
  • As you can see in the description I'm using a special configuration 'CustomBinding' (GetCustomBinding) that is already working, the problem is that WCF can't understand the response that has no SOAP head at all. – rasputino Nov 25 '19 at 11:40
  • MutualCertificate authentication mode might be a worthy try, but we should establish two-way trust relationship. Since the server using Http+SSL, why did you say there is no certificate to trust? – Abraham Qian Nov 26 '19 at 03:17
  • Because the server uses ssl but has no certificate configured – rasputino Nov 28 '19 at 08:20
  • that's not the case. the server at least needs to binds one certificate to the port, so as to work over HTTPS. depending on the type of certificate used by the server , we either ask the service provider for the root certificate or directly download the certificate by the browser address bar(service WSDL page). Then we install it in the local CA(trusted root certification Authorities) – Abraham Qian Nov 28 '19 at 08:34
  • This is one procedure to trust the server certificate, we also need to trust the client certificate on the server-side. – Abraham Qian Nov 28 '19 at 08:45
  • Is a third party web server, it uses https but has no certificate – rasputino Dec 02 '19 at 09:50