I am using RestAssured Java library to test REST API, and need to use certificate when invoking the API. I've come across the following stackoverflow link How to make HTTPS GET call with certificate in Rest-Assured java, but none of the solution seems to work.
In RestAssure official Java Doc, I find this page: https://www.javadoc.io/doc/io.rest-assured/rest-assured/3.2.0
In the sub link that points to io.restassured.config, Class SSLConfig, there's this statement:
"Now you want to use this truststore in your client:"
RestAssured.config = RestAssured.newConfig().sslConfig(new SSLConfig("/truststore_javanet.jks", "test1234");
"or"
given().config(newConfig().sslConfig(new SSLConfig("/truststore_javanet.jks", "test1234"))
Is this kidding? Because if you look at the SSLConfig constructor
SSLConfig()
It does not accept path and password string as parameter at all. And that's what my IDE says too.
Has anyone get their code working at all?
Also the usual logging functionality 'RestAssured log.all()' does not seem to log any certificate related info when sending http requests.
Even if I made up some code like:
RestAssured.config = newConfig().sslConfig(new SSLConfig().trustStore("src/test/resources/certs/trust.jks", "password"));
It does not throw error if I give a non-existing file path value for the parameter.
So I am stuck. With no sample code to follow, or RestAssured printing any helpful info for me to debug certificate related issue.
Related
I have a spring-boot application for which i am writing integration tests
I'm trying to use hoverfly-java to capture the traffic for an external system i am using. My test runs fine when i dont add hoverfly, but on adding this line:
#ClassRule
public static HoverflyRule hoverflyRule = HoverflyRule.inCaptureOrSimulationMode("simulation.json");
My external system returns a 500 and I see the following error
POST abc/login: x509: certificate signed by unknown authority
How to I update my resttemplate to fix this?
Actally, rather than me asking questions I can guess that if it is the case of being self-signed, you can try using the -tls-verification command in Hoverfly as documented here:
http://hoverfly.readthedocs.io/en/v0.13.0/pages/reference/hoverfly/hoverflycommands.html?highlight=tls
However, I have noticed that this is not configurable through Hoverfly Java. Try using the Hoverfly binary directly to prove that it is indeed the fix, and if that is the case raise a GitHub issue and we will make it configurable in the Java binding.
Disabling TLS verification solved the issue for me.
May be you didn't try the correct command.
Try hoverfly -tls-verification=false
You should see TLS certificate verification has been disabled
in the logs.
Hope this helps.
I have a Spring Boot application that uses spring-yarn-boot:2.2.0.RELEASE to get access to a Hadoop filesystem (HDFS). Operations that I do are LISTSTATUS, GETFILESTATUS and OPEN (to read a file). HDFS URI is specified through application.properties:
spring.hadoop.fsUri=webhdfs://127.0.0.1:50070/webhdfs/v1/
I make a bean to which I provide Hadoop Configuration (that Spring somehow automagically prepares for me on startup):
SimplerFileSystem fs = new SimplerFileSystem(FileSystem.get(configuration));
FsShell shell = new FsShell(configuration);
And everything works well as expected, but the problems came when I got two new requirements.
First thing is that HDFS will be protected with SSL from now on. I can't seem to find any way to tell my application that the fsURI that starts with webhdfs:// is actually a https connection. And if I will give the https URL directly, I'll get an exception:
java.io.IOException: No FileSystem for scheme: https
at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2584)
... which is caused by that code: FileSystem.get(configuration).
This thing is driving me crazy, I don't seem to find a way to get pass this.
Second requirement is, that I need to authenticate myself against the WebHDFS with basic authentication. For this I also can't find any means in the client API.
Has anyone done it before and have any instructions to share? Or maybe anyone knows a different client API that I can use to accomplish this?
One option is to implement the REST calls myself with RestTemplate or any other REST service consumer API, but this looks like not-so-special use case so I'm really hoping that there is something that has been done already.
EDIT:
Found a solution to the HTTPS problem. One should use swebhdfs:// as url prefix and everything will work. Still havent found a solution to the Basic Auth problem.
I'm using EWS Java API to connect Exchange server and retrieve information about mail, calendar appointment and task.
It's working well with a lot of user, except for one account.
I got the following error :
microsoft.exchange.webservices.data.EWSHttpException: Connection not established
at microsoft.exchange.webservices.data.HttpClientWebRequest.throwIfConnIsNull(HttpClientWebRequest.java:394)
at microsoft.exchange.webservices.data.HttpClientWebRequest.getResponseHeaders(HttpClientWebRequest.java:280)
at microsoft.exchange.webservices.data.ExchangeServiceBase.processHttpResponseHeaders(ExchangeServiceBase.java:1045)
at microsoft.exchange.webservices.data.SimpleServiceRequestBase.internalExecute(SimpleServiceRequestBase.java:58)
at microsoft.exchange.webservices.data.MultiResponseServiceRequest.execute(MultiResponseServiceRequest.java:144)
at microsoft.exchange.webservices.data.ExchangeService.bindToFolder(ExchangeService.java:350)
at microsoft.exchange.webservices.data.ExchangeService.bindToFolder(ExchangeService.java:374)
Here the code to establish the connection :
ExchangeService service = new ExchangeService();
ExchangeCredentials credentials = new WebCredentials(<user>, <password>);
service.setCredentials(credentials);
service.setUrl(new URI(url));
I suspect a specific account configuration for explaining this error but I'm unable to determine which parameter.
That exception is almost certainly due to a bug. I've seen it many, many times. The problem lies in the SimpleServiceRequest class. If there's an error when reading the response, it will close the response in a finally block in readResponse(). It will go back up to internalExecute(), where the catch block will try to process the headers...and it tries to read the response that has been closed. The closing won't null out the response, but it does null out some data in the response, which EWS tries to read as to display errors. Then you get another exception because the connection is null due to the response being closed earlier.
The solution is to either fix the bug yourself or enable tracing and look at the response to see what kind of error you're dealing with. Also, for good measure, make sure the Strings class is reading in the Strings.properties file or it'll throw a different exception when it can't find certain error messages.
After working with the debugger and Fiddler, one way I've seen this error coming in is from an HTTP 302 error (the server says the link has been moved permanently to an https: location instead of the almost identical http: location).
I'm going to guess that the Java EWS API is not using the Secure Sockets Layer correctly (and is attempting to send to an HTTP url instead of an HTTPS url).
EDIT
If you get past the 302 error, then you may very well have a problem with handling the SSL certificate properly later on. If you debug the API, you may be able to see one of those
"PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"
errors in on the stack in ServiceRequestBase.java. That means that a Truststore, somewhere cannot find a certificate, or it's not looking in the right place.
UPDATE
Check which NTLM flags are getting set in the EwsJCIFSNTLMScheme class. I've seen connections fail because these flags were getting set wrong.
Use something like Fiddler to automatically (and successfully) authenticate into your EWS instance, check and see what NTLM flags are getting set (by decoding the Authorization: Negotiate headers with Fiddler in the "Inspectors", "Auth" tab - it's a 32-bit hex number), and send those hex-valued flags into the Type1 and Type3 message constructors.
I have the same error in china.I think it's ews-java-api bug .so I check the github.com,I see the author Victor Boctor update the scrip.so I think maybe it can fix this bug.so try to compile the source code,and sure ,it fix this bug. ~_~ thanks for Victor Boctor
As a premise, I am not very experienced yet, but I have tried to read and search everything I possibly could, related to this topic, and still no luck.
I was given a simple client to call a webservice but once it was fully setup (which included the use of a certificate and a couple more properties to set) I got the error mentioned in the title:
javax.xml.ws.WebServiceException: {http://http://cert.controller.portaapplicativa.ictechnology.it//}MyService is not a valid service. Valid services are:
at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:187)
at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:159)
at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:82)
at javax.xml.ws.Service.<init>(Service.java:56)
at package.client.wsimport.MyService..<init>(MyService.java:46)
at package.client.Client.doRicercaDEN(Client.java:55)
at package.client.Client.main(Client.java:36)
I tried generating the client again with JAX-WS:
java -classpath C:\Programmi\Java\jdk1.6.0_38\lib\tools.jar com.sun.tools.internal.ws.WsImport -verbose C:\WsdlFile.wsdl -p package.client.wsimport -s C:\tmp\ws\
And I get the same issue. I am using a local copy of the wsdl because wsimport doesn't seem to like the certificate I'm trying to set in the properties (I'm most likely doing something wrong, but I opted for the simple workaround, given I have more pressing issues).
Trying to use SoapUI to test the service, everything works fine, though I need to set the preferences for the proxy to "None".
So I tried to make sure the connection doesn't use any proxy in my client as well:
(...)
systemSettings.remove("http.proxyHost");
systemSettings.remove("http.proxyPort");
systemSettings.remove("https.proxyHost");
systemSettings.remove("https.proxyPort");
System.setProperty("http.nonProxyHosts","*");
System.setProperty("https.nonProxyHosts","*");
(BTW, before "*", which as I understand it should work as a wildcard for "every domain", I have tried specifying the specific domains as well)
Anyway, the result is always the same.
Is there something I am doing wrong, something left to try?
I doubt this is a proxy issue. If you can share the code you are using to create the Service object it might help.
As a kick start try reading the below thread Is not a valid service exception in JAX-WS
What I think is that the QName you have provided when creating the Service is not proper. To get the correct QName you might try to open the generated stub.
As it turns out, what I was missing was importing the certificate in my local truststore (or better, when I first tried doing so, I thought I was using the correct truststore, but I wasn't).
For anyone who may need it, here is an explanation of how to do that using keytool: http://javarevisited.blogspot.it/2012/03/add-list-certficates-java-keystore.html
Another option is to use specific GUI like Portecle.
I am rewriting example code for access to the API of a web store from Java into classic ASP. The Java code works, it sends requests and the right results are returned. The ASP code does exactly the same but all it does is return an error that there is something wrong with the authorization. I have checked the hmac signature string (sha256, base64) but this gives the same results as the Java code.
So then I decided to check how the HTTP requests actually look, and compare them with each other. Fiddler seemed to be a good choice, but for some reason both HTTP request dont show up.
A lot has already been written on this subject and i tried several things, but so far no luck. They all describe routing the request through the Fiddler proxy, which is localhost:8888.
I use this object in the ASP code:
Set httpRequest = Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
For IIS 7 (on Windows 7) the proxy can be set in DOS like this:
netsh winhttp set proxy localhost:8888
And in the code like this (this may not work in other version of "MSXML2.ServerXMLHTTP" than v6):
httpRequest.setProxy 2, "http=localhost:8888", ""
The Java code uses Apache HttpClient, and according to the manual the proxy can be set like this:
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpHost proxy = new HttpHost("localhost", 8888);
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
I added this code at the beginning of the main() method. The code is run inside Eclipse (Juno).
I also opened the proxy address (http://localhost:8888/) in a browser, and it shows me the 'Fiddler Echo Service' page. Fiddler is set to show 'All Processes'.
Still, none of two HTTP Request show up. The only thing that does show up is the ASP page I run (http://localhost:8082/test.asp) that does the HTTP request. When I use my browser other things show up on Fiddler, so I know it is working.
Anybody got any ideas?
I originally thought that because nothing showed up on Fiddler with both programs, something was wrong with Fiddler.
But things were wrong with both programs. For the ASP code, setProxy has to called like this:
xmlhttp.setProxy 2, "http://127.0.0.1:8888", ""
So "::/" instead of "="
Making Apache HttpClient requests in the Java code show up in Fiddler was very complicated because request were send using https protocol. Although I tried several proposed solutions, I could not get it to work.
In the end I found out that adding
-Djavax.net.debug=all
as an argument for the VM showed me the what I needed, the headers that were being send.