简体   繁体   中英

How to consuming the WSDL web service using Pkcs12 keystore certificate

I need to consume a third-party web service. I have a WSDL file and .pkcs12 Keystore file & password. Using that WSDL file I have added web reference in the project. read the Keystore file. Created a new instance of X509certificate2 class and imported the certificate after adding to the service class. I am trying to call method in my service

            service.mymethod(param1)--> (At this line its throwing error stating that ws-security header not found)

by googling the error I found StackOverflow link to add security header after following that link here is complete code

                //reading PCKS12 certificate
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content\\myKeyStoreFile.pkcs12");
                var data = System.IO.File.ReadAllBytes(path);
                //Importing Certificate
                X509Certificate2 certificate = new X509Certificate2();
                certificate.Import(data, "password", X509KeyStorageFlags.DefaultKeySet);
                //adding WS-Security Headers
                UsernameToken token = new UsernameToken("keyname", "password", PasswordOption.SendHashed);
                service.RequestSoapContext.Security.Tokens.Add(token);
                //adding certificate to service
                service.ClientCertificates.Add(certificate);
                //calling proxy class(service method)
                service.methodname(param1);-->(its throwing System.web.service.protocols.soapheaderexception:'nested exception is org.apache.wss4j.common.ext.WSSSecurityException Original Exception was javax.security.auth.callback.unsupportedcallbackexception)

I have a java code(implemented in spring boot) for reference. Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();

    //crypto varible contains .pkcs12 file path and password properties
    Crypto crypto = null;
    try {
        crypto = CryptoFactory.getInstance(cryptoPropertyFile);
    }catch(WSSecurityException e) {
        e.printStackTrace();}
    securityInterceptor.setSecurementActions("Encrypt Signature");
    securityInterceptor.setSecurementEncryptionUser(trustedCertKeyAlias);
    securityInterceptor.setSecurementEncryptionCrypto(crypto);
    securityInterceptor.setSecurementEncryptionParts("{Content {http://schemas.xmlsoap.org/soap/envelope/}Body");
    securityInterceptor.setSecurementUsername(privateKeyAlias);
    securityInterceptor.setSecurementPassword(privateKeyPassword);
    securityInterceptor.setSecurementSignatureCrypto(crypto);
securityInterceptor.setSecurementSignatureKeyIdentifier("DirectReference");
    securityInterceptor.setSecurementSignatureUser(privateKeyAlias);
    securityInterceptor.setSecurementSignatureParts("{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body");        
    securityInterceptor.setValidationActions("Encrypt");
    securityInterceptor.setValidationDecryptionCrypto(crypto);
    KeyStoreCallbackHandler keyStoreCallbackHandler = new KeyStoreCallbackHandler();
    keyStoreCallbackHandler.setPrivateKeyPassword(privateKeyPassword);
securityInterceptor.setValidationCallbackHandler(keyStoreCallbackHandler);
    LogHttpHeaderClientInterceptor logHttpHeaderClientInterceptor = new LogHttpHeaderClientInterceptor();
    ClientInterceptor[] interceptors = {securityInterceptor, logHttpHeaderClientInterceptor};
    template.setInterceptors(interceptors);

Can any one please let me know how to add interceptors in dotnet. I have done some research but couldn't find any solution. Is there any thing that smilar to Wss4jSecurityInterceptor in dotnet.

IClientMessageInspector might be something you're after.

You need to create IEndpointBehavior and add IClientMessageInspector to your behavior, then add the behavior to the endpoint used to create ChannelFactory .

See: https://docs.microsoft.com/en-us/dotnet/framework/wcf/extending/how-to-inspect-or-modify-messages-on-the-client

Also see: https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.dispatcher.iclientmessageinspector?view=netframework-4.8

Example:

class MyEndpointBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add(new MyMessageInspector());
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
}

class MyMessageInspector : IClientMessageInspector
{
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        return null;
    }
}

Use message inspector:

var endpoint = new EndpointAddress("<your webservice uri>");
var binding = new BasicHttpBinding(); // Assume you are using HTTP binding
var channelFactory = new ChannelFactory<Soap>(binding, endpoint);
channelFactory.Endpoint.EndpointBehaviors.Add(new MyEndpointBehavior());
var client = channelFactory.CreateChannel();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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