Tomcat - Getting Java SSLException hostname in certificate didn't match - java

On my machine (on a main method) I am able to consume an https web service using this code:
URL url;
HttpsURLConnection connection;
HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){
public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession) {
return true;
}
});
//prepare the request
byte[] postData = xml.getBytes(StandardCharsets.UTF_8);
int postDataLength = postData.length;
url = new URL(ENDPOINT_URL);//https endpoint
connection = (HttpsURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
connection.setRequestProperty("Content-Length", Integer.toString(postDataLength));
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.write(postData);
//make the request and get response xml string
connection.getResponseCode();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
Notice that on the code I bypass hostname verification, according to the answers to this post: Java SSLException: hostname in certificate didn't match
But if I try to consume the exact same https web service, using the exact same code, on the the exact same machine (my local machine), but from a webapp deployed on Tomcat 8, I get the error:
Caused by: javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException: No name matching localhost found
I have searched for anwsers and solutions to this problem but found none. I am clueless. Do you have any idea why is this happening?

Related

MailChimp Integration in Java

I want to integrate MailChimp API in my java project. When I call Rest call using HttpURLConnection class, it responds with 401 code.
Here is my code:
URL url = new URL("https://us13.api.mailchimp.com/3.0/lists");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "apikey <my-key>");
String input = "<json data>";
OutputStream os = conn.getOutputStream();
//os.write(input.getBytes());
os.flush();
if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
I will suggest using Apache Commons Codec package for encoding.
It support various formats such as Base64 and Hexadecimal.
Earlier I was also facing the same issue. I am sharing the code that I used in my application for authenticating to Mailchimp API v-3.0
//basic imports
import org.apache.commons.codec.binary.Base64;
.
.
.
//URL to access and Mailchimp API key
String url = "https://us9.api.mailchimp.com/3.0/lists/";
//mailchimp API key
String apikey = xxxxxxxxxxxxxxxxxxxxxxxxxxx
// Authentication PART
String name = "Anything over here!";
String password = apikey; //Mailchimp API key
String authString = name + ":" + password;
byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
String authStringEnc = new String(authEncBytes);
URL urlConnector = new URL(url);
HttpURLConnection httpConnection = (HttpURLConnection) urlConnector.openConnection();
httpConnection.setRequestMethod("GET");
httpConnection.setDoOutput(true);
httpConnection.setDoInput(true);
httpConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
httpConnection.setRequestProperty("Accept", "application/json");
httpConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
InputStream is1 = httpConnection.getInputStream();
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(is1, "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
Now you can use StringBuilder Object sb to parse the output as required
Hope it resolves your issue :)
HTTP 401 response code means "not authorized".
You didn't set or pass your credentials properly. Is the certificate from the client set up? Here's an example of an HTTPS client.
HTTP 401 simply means you're not Authorized to send this request.
you can set username any string (the MailChimp docs suggest using anystring as a username) and your API key as a password.
In case of Postman request, you can set under the Authorization tab choose Basic Auth to set username and password. Below image shows the same.
More info about Adding/ Getting Members to/ from a Mailing List on MailChimp API 3.0, I find this article very useful.

Send http post request to URL with query string using HttpPost client in java

I need to send a post request to url which is formed as follows:
www.abc.com/service/postsomething?data={'name':'rikesh'}&id=45
Using HttpPost client in java, how can post request to such query strings
I could connect from javascript easily through ajax but from java client, it's failing.
(I know sending querystring in post request is stupid idea. Since I am connecting to someone else's server I cannot not change the way it is)
Here is one way to send JSON in a POST request using Java (without Apache libraries). You might find this helpful:
//init
String json = "{\"name\":\"rikesh\"}";
String requestString = "http://www.example.com/service/postsomething?id=45";
//send request
URL url = new URL(requestString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
OutputStream os = conn.getOutputStream();
os.write(json.getBytes());
os.flush();
int responseCode = conn.getResponseCode();
//get result if there is one
if(responseCode == 200) //HTTP 200: Response OK
{
String result = "";
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String output;
while((output = br.readLine()) != null)
{
result += output;
}
System.out.println("Response message: " + result);
}

HttpURLConnection always return error 500

i'm trying to run a soap request in a basic http request...naturally i tried with external tools the message and is correct, like the endpoint i'm using as targetUrl, the wsdl is in something like
http://00.00.00.00/a-ws/services/basic?wsdl
and my actual end point is
http://00.00.00.00/a-ws/services/basic.targetservice
and i'm using this last as target url
URL url = new URL(targetUrl);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
connection.setRequestProperty("SOAPAction", action);
connection.setRequestProperty("User-Agent", "myagent");
connection.setRequestProperty("Host", "localhost");
//connection.setRequestProperty("Content-Length", "" + Integer.toString(message.getBytes().length));
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(true);
//Send request
OutputStream wr = connection.getOutputStream ();
wr.write (message.getBytes());
wr.flush ();
wr.close ();
//Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line=null;
StringBuffer response = new StringBuffer();
while( (line = rd.readLine()) != null) {
if (line!=null)
response.append(line);
}
rd.close();
return response.toString();
the raw message is tested with chrome plugin, the only thing i can't test is headers but the result is always an exception on getInputStream
java.io.IOException: Server returned HTTP response code: 500 for URL:
why?
It was a very stupid issue of encoding (like I was supposing)...i didn't escape double quote inside the message.
The evidence of problem was visible using a fake http server that just echo contents.
UPDATE:
Another thing nobody already pointed out is that is useful in case of exception to retrieve
connection.getErrorStream()
that contains the response in case of error!

IOException when trying to read http connection response

I'm submitting the request below in Java via a Websphere Portlet.
It works fine when I submit manually using postman (chrome extension) but cannot get it to succeed via java.
What am I missing?
I imported the SSL cert from remote host into Websphere, so SSL connections are not the issue.
Exception in logs ..
[7/15/14 23:06:39:993 BST] 00000170 ServletWrappe E com.ibm.ws.webcontainer.servlet.ServletWrapper service CWSRV0014E: Uncaught service() exception root cause MyApp: java.io.IOException: Server returned HTTP response code: 500 for URL: https://server.com/msg
This is the java code invoking the request and trying to read the response ..
URL url = new URL("https://server.com/msg");
URLConnection connection = url.openConnection();
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
String body = URLEncoder.encode("{\"x\": \"hello\"}", "UTF-8");
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(body);
out.close();
// Exception occurs here ..
BufferedReader rd2 = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = rd2.readLine()) != null) {
result += line;
}
rd2.close();
This was solution, to not URLEncoder.encode() the POST body ..
URL url = new URL(queries.getQuery(sessionBean.getSelectedQuery()));
URLConnection connection = url.openConnection();
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
String json = "{\"x\": \"hello\"}";
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(json);
out.close();
BufferedReader rd2 = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = rd2.readLine()) != null) {
result += line;
}
rd2.close();

Manually hitting a SOAP Service in Java, getting IO.FileNotFound exception

I need to access a .Net SOAP Service manually. All the importers have issues with its WSDL, so I'm just manually creating the XML message, using HttpURLConnection to connect, and then parsing the results. I've wrapped the Http/SOAP call into a function that is supposed to return the results as a string. Here's what I have:
//passed in values: urlAddress, soapAction, soapDocument
URL u = new URL(urlAddress);
URLConnection uc = u.openConnection();
HttpURLConnection connection = (HttpURLConnection) uc;
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("SOAPAction", soapAction);
connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
connection.setRequestProperty("Accept","[star]/[star]");
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
//helper function that gets a string from a dom Document
String xmldata = XmlUtils.GetDocumentXml(soapDocument);
wout.write(xmldata);
wout.flush();
wout.close();
// Response
int responseCode = connection.getResponseCode();
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String responseString = "";
String outputString = "";
//Write the SOAP message response to a String.
while ((responseString = rd.readLine()) != null) {
outputString = outputString + responseString;
}
return outputString;
My problem is on the line BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream())); I get a "java.io.FileNotFoundException" with the address that I'm using (i.e. urlAddress). If I paste that address into a browser, it pulls up the Soap Service webpage just fine (address is http://protectpaytest.propay.com/API/SPS.svc). From what I've read, the FileNotFoundException is if the HttpURLConnection returns a 400+ error message. I added the line getResponseCode() just to see what the exact code was, and it's 404. I added the User-Agent and Accept headers from some other pages saying they were needed, but I'm still getting 404.
Are there other headers I'm missing? What else do I need to do to get this call to work (since it works in a browser)?
-shnar

Categories