Accessing JAX-WS webservice from C# issue - java

I have to use a SOAP web service in a VPN network (so you couldn't test it), written in Java (JAX-WS webservice).
I don't have access at server side. When i try to call a web method from a C# 4.0 client I get this exception:
The CustomBinding on the ServiceEndpoint with contract 'ServicesSoap' lacks a TransportBindingElement. Every binding must have at least one binding element that derives from TransportBindingElement.
at System.ServiceModel.Channels.Binding.EnsureInvariants(String contractName)
at System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint serviceEndpoint, Boolean useActiveAutoClose)
at System.ServiceModel.ChannelFactory.CreateFactory()
at System.ServiceModel.ChannelFactory.OnOpening()
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.ChannelFactory.EnsureOpened()
at System.ServiceModel.ChannelFactory`1.CreateChannel(EndpointAddress address, Uri via)
at System.ServiceModel.ClientBase`1.CreateChannel()
at System.ServiceModel.ClientBase`1.CreateChannelInternal()
at System.ServiceModel.ClientBase`1.get_Channel()
at GatewayClient.Lotto.ServicesSoapClient.GatewayClient.Lotto.ServicesSoap.InfoRequest(InfoRequestRequest request)
at GatewayClient.Lotto.ServicesSoapClient.InfoRequest(infoDataIn request)
at GatewayClient.MainWindow.InfoRequestButton_Click(Object sender, RoutedEventArgs e)
This is my app.config:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="ServicesSoapPortBinding">
<textMessageEncoding messageVersion="Soap12" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://xxx.yyy/Services"
binding="customBinding" bindingConfiguration="ServicesSoapPortBinding"
contract="ServiceReference1.ServicesSoap" name="ServicesSoapPort" />
</client>
</system.serviceModel>
Any help?

I've solved the issue adding httpTransport in the binding tag, in the app.config:
<binding name="ServicesSoapPortBinding">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport/>
</binding>
I have to add the service reference within Visual Studio "Service References" feature. Trying to use svcutil, I get another different exception.

Related

WSO2 problem during Proxy Service for SOAP to REST transformation

I'm new on WSO2 and for a huge project we are using the EI 6.1.1.
One of our goals is to create some REST services that must substitutes some legacy SOAP services: for do that, we are developing Spring Boot REST and our idea is to expose these one in a SOAP way, with same WSDL of the legacy service.
We are creating a Proxy Service on WSO2 and we are able to call the rest service in backend, but, even if the REST logging show us that everything goes fine, the SOAP call never send back response, and "die" with a read timeout.
How can we fix that? I'll post you the proxyService configuration:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="VerificaAmbitiSET_SOAP_AWS"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="http,https">
<target>
<inSequence>
<filter xmlns:ver="http://XXXXXX.XXXXXX.XXXXXX"
xpath="//ver:getAmbitiSet">
<then>
<property expression="//ver:getAmbitiSet/ver:codiceFiscale"
name="REST_URL_POSTFIX"
scope="axis2"
type="STRING"/>
<property name="HTTP_METHOD" scope="axis2" type="STRING" value="GET"/>
</then>
<else/>
</filter>
<header name="Accept" scope="transport" value="*/*"/>
<send>
<endpoint>
<address format="rest"
uri="http://localhost:8280/services/A_SERVICE/ambitiSet"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<publishWSDL key="conf:/wsdl/A_WSDL.wsdl"/>
<description/>
</proxy>
and this is the REST controller sign:
#GetMapping(value = "/ambitiSet/{codiceFiscale}")
public List<Ambito> getAmbitiSET(#PathVariable("codiceFiscale") String codiceFiscale)
Finally, my SOAP request looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ver="http://XXXX.XXXXX.XXXXXX">
<soapenv:Header/>
<soapenv:Body>
<ver:getAmbitiSet>
<ver:codiceFiscale>XXZXZXZXZ</ver:codiceFiscale>
</ver:getAmbitiSet>
</soapenv:Body>
</soapenv:Envelope>
Greeting.
You can test where the response is getting dropped via enabling wire logs. Please follow the blog https://medium.com/#tharika/how-to-read-and-understand-wire-logs-in-wso2-products-c384af0b8ea5

Security Policy Error Calling Java Web Service From .Net

I am trying to call a Java web service, over Http not Https, using .Net. The only hint I got from the web service team is to pass the credential either in SOAP message or in the endpoint settings.
I have created a simple console application and added a service reference to the web service. The following is the generated binding (I see that there is warning about unrecognized policy but cannot figure what it means or whether it is relevant or not):
<customBinding>
<binding name="CurrencyInformationServiceSoapBinding">
<!-- WsdlImporter encountered unrecognized policy assertions in ServiceDescription 'http://www.openuri.org/': -->
<!-- <wsdl:binding name='CurrencyInformationServiceSoapBinding'> -->
<!-- <ns1:SupportingTokens xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512">..</ns1:SupportingTokens> -->
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap11" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<!--<security authenticationMode="UserNameOverTransport" allowInsecureTransport="true"/>-->
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
Here are my trials:
Trail #1:
-----------
Using the following code:
CurrencyInformationServiceClient client = new CurrencyInformationServiceClient();
foreignCurrencyDTO[] results = client.getAllForeignCurrencies();
or supplying the credentials in Windows property
CurrencyInformationServiceClient client = new CurrencyInformationServiceClient();
client.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("crmuser", "welcome1");
foreignCurrencyDTO[] results = client.getAllForeignCurrencies();
or supplying the credentials in UserName property
CurrencyInformationServiceClient client = new CurrencyInformationServiceClient();
client.ClientCredentials.UserName.UserName = "someuser";
client.ClientCredentials.UserName.Password = "somepassword";
foreignCurrencyDTO[] results = client.getAllForeignCurrencies();
resulted in
System.ServiceModel.FaultException: Error on verifying message against security policy Error code:1000
Trail #2:
-----------
As per one comment I have seen, I have tried to add the following tag in the binding and call the web service by passing the credentials in UserName property of ClientCredentials
<security authenticationMode="UserNameOverTransport" allowInsecureTransport="true"/>
but the result was
System.ServiceModel.Security.MessageSecurityException: Security processor was unable to find a security header in the message. This might be because the message is an unsecured fault or because there is a binding mismatch between the communicating parties. This can occur if the service is configured for security and the client is not using security.
Trail #3:
-----------
I have tried to use WSHttpBinding instead of the CustomBinding generated by VS as follows:
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
EndpointAddress ea = new EndpointAddress("http://someurl/CurrencyInformationService.jws");
CurrencyInformationServiceClient client = new CurrencyInformationServiceClient(binding, ea);
client.ClientCredentials.UserName.UserName = "someuser";
client.ClientCredentials.UserName.Password = "somepassword";
foreignCurrencyDTO[] results = client.getAllForeignCurrencies();
but the result was
System.ServiceModel.ProtocolException: Content Type application/soap+xml; charset=utf-8 was not supported by service http://someurl/CurrencyInformationService.jws. The client andservice bindings may be mismatched. ---> System.Net.WebException: The remote server returned an error: (415) Unsupported Media Type.
Update:
-----------
I have received a working request from the vendor and tried it in soapUI and it gave a correct response.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<wsse:Security soap:mustUnderstand="1">
<wsse:UsernameToken wsu:Id="SecurityToken-35598fb7-5aa2-4623-b07b-3277c6578beb" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>someuser</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">somepassword</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<getAllForeignCurrencies xmlns="http://www.openuri.org/">
</getAllForeignCurrencies>
</soap:Body>
</soap:Envelope>
Can someone give me a hint how to generate such a SOAP request?
I was facing the same issue while consuming a java web service using .Net, and this thread helped me partially in being able to consume web service.
But, somehow I came across this post and it worked as a final solution for me : http://weblog.west-wind.com/posts/2012/Nov/24/WCF-WSSecurity-and-WSE-Nonce-Authentication
Below settings worked fine for me:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomSoapBinding">
<security includeTimestamp="false"
authenticationMode="UserNameOverTransport"
defaultAlgorithmSuite="Basic256"
requireDerivedKeys="false"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
</security>
<textMessageEncoding messageVersion="Soap11"></textMessageEncoding>
<httpsTransport maxReceivedMessageSize="2000000000"/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://notrealurl.com:443/services/RealTimeOnline"
binding="customBinding"
bindingConfiguration="CustomSoapBinding"
contract="RealTimeOnline.RealTimeOnline"
name="RealTimeOnline" />
</client>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0"
sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
If you use SSL use this:
<basicHttpBinding>
<binding name="NewBinding0">
<security mode="TransportWithMessageCredential" />
</binding>
</basicHttpBinding>
If no SSL then use CUB.

How to configure Userid/Password on a client side for a WCF service in config file and not in code

Requirement is to call a Java Web Service. There is a WSDL provided. Call is successful in unsecured fashion. Now the service call needs to be authenticated. Service call will be successful only via a paricular windows userid/password. Since everything in our application is config based, we don't want to hard-code anything in code. Appreciate if someone can show how to do so ?
I have this config by the way....
<basicHttpBinding>
<binding name="MyBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:30:00" sendTimeout="00:10:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
You can't set the username/password anywhere in the WCF-specific configuration. You can, however, set the username/password pair as application settings, retrieve them from the code, and set them in the WCF client.
<configuration>
<appSettings>
<add key="UserName" value="My user name" />
<add key="Password" value="Your secret password" />
</appSettings>
</configuration>
and in the code:
var username = ConfigurationManager.AppSettings["UserName"];
var password = ConfigurationManager.AppSettings["Password"];
client.ClientCredentials.UserName.UserName = username;
client.ClientCredentials.UserName.Password = password;

Web Service Custom Binding - sign SOAP header and message, but don't encrypt

I am trying to figure out how to call a Java Web Service (blackbox) from .NET which expects each request to be signed with a certificate (which is no problem).
I don't get it. Whatever I try, it fails. After spending hours with researching and testing I think the right way should be to use a customBinding instead of a basicHttpBinding. What I want to achieve is to sign the header as well as the message body.
By using authentication mode CertificateOverTransport only the SOAP header is signed, not the body. By using authentication mode MutualCertificate everything is signed and encrypted.
Do I have any chance to disable the encryption of the whole message?
I got it.
Binding:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="FFB">
<context protectionLevel="Sign" />
<textMessageEncoding messageVersion="Soap11" />
<security authenticationMode="MutualCertificateDuplex" includeTimestamp="true" />
<httpsTransport />
</binding>
</customBinding>
</bindings>
</system.serviceModel>
</configuration>
And additionally:
service.Endpoint.Contract.ProtectionLevel = ProtectionLevel.Sign;

Why do I get a bad_certificate error when using spring and CXF

I am using CXF generated code to connect to a remote web service over SSL and through a corporate proxy. The code works fine when the connection is established through the Java API and all SSL settings are set as system properties as follows.
System.setProperties("https.proxyHost", "myproxy.com");
System.setProperties("https.proxyPort", "8001");
System.setProperties("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperties("javax.net.ssl.keyStore", "C:/keystore.p12");
System.setProperties("javax.net.ssl.keyStorePassword", "keypassword");
System.setProperties("javax.net.ssl.trustStore", "C:/cacerts");
System.setProperties("javax.net.ssl.trustStorePassword", "capassword");
MyWebService_Service ss = new MyWebService_Service(wsdlUrl, SERVICE_NAME);
MyWebService service = ss.getMyWebServicePort();
Using this code I can now call the service methods and everything works as expected. My problems occur when I try to set up the same configuration with Spring, which is our preferred approach since we are already using Spring extensively.
My Spring config:
<!-- relevant snippet from spring context -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-http.xml" />
<jaxws:client id="webservice" serviceName="myns:MyWebService" endpointName="myns:MyWebServicePort"
address="https://bigserver.com:5012/blah/TheWebService"
serviceClass="com.mycomp.MyWebService" />
<http:conduit name="{myns}MyWebServicePort.http-conduit">
<http:tlsClientParamenters disableCNCheck="true" secureSocketProtocol="TLS">
<sec:trustManagers>
<sec:keyStore type="JKS" password="capassword" file="c:/cacerts" />
</sec:trustmanagers>
<sec:keyManagers>
<sec:keyStore type="pkcs12" password="keypassword" file="c:/keystore.p12" />
</sec:keyManagers>
</http:tlsClientParamenters>
<http:client ProxyServer="myproxy.com" ProxyServerPort="8001" />
</http:conduit>
In both cases, the web service client is deployed within a web application. In the second case, access to the web service results in a
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
Edit: I am using CXF version 2.2.
Have you tried adding the next property to your client parameters?
**useHttpsURLConnectionDefaultHostnameVerifier="false"**
Looks like this:

Categories