When I invoke my Webservice I am getting error like below, please explain it how I can solve this problem.
Error is:
fault Description : nulldetail : faultCode:Server.Processing
faultString:'javax.net.ssl.SSLHandshakeException : General SSLEngine
problem' faultDetail:'null'
I am using tomcat server in my local.
I'm using 1.6 Java Runtime Environment and I added Webservice SSL into:
jdk1.6>jre>lib>security>cacerts .
but nothing changed. Do I need configure my tomcat server
I solved the problem . You dont need to any configuration your server . Or JRE .
Just put it this code
public String retrieveMngTracking(ArrayList paramList) throws Exception {
//ı added for SSL
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName
+ " vs. " + session.getPeerHost());
return true;
}
};
ParamMap paramMap = FlexUtil.getParamMap(paramList);
URL url = new URL(paramMap.getString("url"));
//Call this function for SSL
trustAllHttpsCertificates();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setReadTimeout(20000);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-type",
"application/x-www-form-urlencoded");
OutputStream os = conn.getOutputStream();
OutputStreamWriter wr = new OutputStreamWriter(os);
wr.write("pMusteriNo=" + paramMap.getString("pMusteriNo"));
wr.write("&pSifre=" + paramMap.getString("pSifre"));
wr.write("&pSiparisNo=" + paramMap.getString("pSiparisNo"));
wr.write("&pKriter=" + paramMap.getString("pKriter"));
wr.flush();
wr.close();
os.close();
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String response = "";
for (;;) {
String line = br.readLine();
if (line == null)
break;
response += line + "\n";
}
br.close();
conn.disconnect();
return response;
}
public static class miTM implements javax.net.ssl.TrustManager,
javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
}
private static void trustAllHttpsCertificates() throws Exception {
// Create a trust manager that does not validate certificate chains:
javax.net.ssl.TrustManager[] trustAllCerts =
new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc =
javax.net.ssl.SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
sc.getSocketFactory());
}
Ok everything perfect in my local my local server is tomcat . But When ı want to deploy Weblogic server same error giving . Please explain it why everything work my local but now weblogic server problem.
Related
I'm trying to get some data by the rest api of Jira. Thiw website is locally in my enterprise and on https. The first time we go on it we are automatically login by SSO. There are certificats too.
I have check all post about this error, try with User-Agent or TrustManager but nothing work :( then I can access to the page by my browser without any problem. It's work on two other computer and I didn't really understand why.
Error I got :
java.io.IOException: Server returned HTTP response code: 403 for URL: https://myjira.xx/rest/api/2/search?jql=project=PARE2+order+by+updated&fields=id,updated,summary,assignee,worklog&startAt=0&maxResults=30
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
And my code is :
public void connectToJira() throws Exception {
String adresse = "https://myjira.xx/";
adresse += "rest/api/2/search?jql=project=NAMEProject+order+by+updated&fields=id,updated,summary,assignee,worklog&startAt=0&maxResults=30";
TrustManager[] trustAllCerts = { new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
} };
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
}
URL url = new URL(adresse);
HttpURLConnection uc = (HttpURLConnection) url.openConnection();
uc.addRequestProperty("User-Agent", "Mozilla/5.0");
uc.setRequestProperty("Authorization", "Basic " + new String(Base64.getEncoder().encode("myUsername:myPassword".getBytes())));
if (401 == uc.getResponseCode()) {
throw new Exception("Code erreur 401");
}
StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(uc.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
System.out.println(sb.toString());
}
I try to add certificats from my cacerts but same problem :(
Thanks
This is my Https client
public String sendHttpsRequest(String httpsUrl, HttpMethod method,
String body, Map<String, String> headers) {
String response = "";
int responseCode = 0;
HttpsURLConnection conn = null;
try {
URL url = new URL(httpsUrl);
conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod(method.toString());
for (Map.Entry<String, String> entry : headers.entrySet()) {
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[]{
new javax.net.ssl.X509TrustManager() {
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
}
}, null);
conn.setSSLSocketFactory(context.getSocketFactory());
String param = body;
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(param);
wr.flush();
wr.close();
responseCode = conn.getResponseCode();
InputStream in = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
response += line;
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(conn != null) {
conn.disconnect();
}
}
return responseCode == 200?response:Integer.toString(responseCode);
}
but for some reason it gives me a "405 Method not allowed" when I try to conncet to https://httpbin.org/get with following parameters.
TreeMap<String, String> map = new TreeMap<>();
map.put("Content-Type", "application/json");
System.out.println(new HttpLiveTest().sendHttpsRequest("https://httpbin.org/get" , HttpMethod.GET, "", map));
I also tried to connect to it through SoapUI with same parameters and it worked there.
I think the certificate that i'm using from Spring might be the problem but I wouldnt know how to solve that issue and why whould it answer with an 405?
Using Wireshark to look at the package didnt work because of TLS
Arnaud said: setDoOutput(true) may force the method to be POST
hes right.
user7236363 wrote:
java.net.ProtocolException: cannot write to a URLConnection if doOutput=false - call setDoOutput(true) is what im getting when i wont set it on true
he is also right.
Big picture:
What you want to do most of the time is a HTTP GET and that passes arguments in on the url - it doesnt requre any bytes to be written after the url so setting the Connection.setDoOutput(true) is not needed at all, hence dont do it when you want to do a GET.
Between the Connection.setRequestProperty(String Key, String Value) and the URL itself you should have everthing you need to make a properly formatted GET request.
I had a very simular problem and the root of it was me setting setDoOutput(true) and not realizing that it had a side effect that i didnt realize (ie setting the request method to post).
I have a java application that is making an HTTP DELETE to an external REST service. This error gets back to me from the server (running C#):
"Value cannot be null.\r\nParameter name: source\n at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source)\r\n at AppCloud_Framework.Controllers.NotificationItemsController.DeleteNotificationItem(NotificationItem[] notificationItems) in C:\\Users\\jonas\\OneDrive\\VS Projects\\AppCloud Framework\\AppCloud Framework\\Controllers\\NotificationItemsController.cs:line 101\nValue:null"
The thing is, when I setup Postman to make the HTTP request to the same URL, with the same Payload and same HTTP method, the action is successful.
I do not have access to the server to investigate further so I need to find the resolution from the client side. Anyway it appears to be a client side issue.
I've been trying to find the problem myself but haven't succeeded. All I could come up with was to add "application/json" to Accept and Content-Type header properties.
My HTTP client:
public static Response execute(String url, Method method, String body) {
Response response = new Response();
try {
////////////////////////////////////////
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
// Install the all-trusting trust manager
final SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
////////////////////////////////////////
URL urlObj = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) urlObj.openConnection();
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod(method.toString());
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
//conn.setRequestProperty("Authorization", _authToken);
if (method == Method.POST || method == Method.PUT || method == Method.DELETE) {
conn.setDoOutput(true);
final OutputStream os = conn.getOutputStream();
os.write(body.getBytes());
os.flush();
os.close();
}
int status = conn.getResponseCode();
//log.info("HTTP request status code: "+status);
InputStream is;
if (status>399){
is = conn.getErrorStream();
}else{
is = conn.getInputStream();
}
if (is==null) return null;
BufferedReader rd = new BufferedReader(new InputStreamReader(is,
"UTF-8"));
String line;
while ((line = rd.readLine()) != null) {
response.body += line;
}
rd.close();
response.statusCode = conn.getResponseCode();
conn.disconnect();
} catch (Exception e) {
//log.error(e.getMessage());
e.printStackTrace();
System.out.println("");
response.exception = e.getMessage();
}
return response;
}
I am making a request with this body(disregard the encoding issue, source of that is somewhere else):
[{"hash":"150a17e99f67ce29fcc600c92eee831d","instanceid":"cb440a6f-44ef-4f05-ab41-143153655b6e","text":"{\"C_FirstAndLastName\":\"und\",\"ContactID\":\"1374231\",\"C_Fax\":\"\"}","queueDate":"2016-10-04T03:18:37"},{"hash":"1a94d9b5acff1a27dfe45be4ca5d9138","instanceid":"fdsfdsf-44ef-4f05-ab41-143153655b6e","text":"{\"C_FirstAndLastName\":\"J?â??rgen\",\"ContactID\":\"323093\",\"C_Fax\":\"fsdfsd-B401-4AD3-AEA1-fdsfsdfsd\"}","queueDate":"2016-10-04T03:18:37"},{"hash":"8e592fb16d464bfd0f90f69818944198","instanceid":"fdsfsdf-44ef-4f05-ab41-143153655b6e","text":"{\"C_FirstAndLastName\":\"Claus\",\"ContactID\":\"2495844\",\"C_Fax\":\"fdsfsdgsd-304D-4E91-8586-fsdfsdfsd\"}","queueDate":"2016-10-04T03:18:37"},{"hash":"d6d226255e62690e50abbfa15c4b5462","instanceid":"cb440a6f-44ef-4f05-ab41-143153655b6e","text":"{\"C_FirstAndLastName\":\"Test J??rgen\",\"ContactID\":\"323093\",\"C_Fax\":\"fdsfsdfsd-B401-4AD3-AEA1-fdsfsdfsdf\"}","queueDate":"2016-10-04T03:18:49"}]
All I had to do was to define encoding in the output stream. Not sure if anyone could help me with that as I have just tried many things and some of it worked, but unfortunately nothing was pointing me into this direction.
os.write(body.getBytes("UTF-8"));
Thanks for your time!
Setup:
I've written a JAVA REST client which authenticates (with username/password) and returns a JSON.
Problem:
This is the exception that I'm getting:
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 401 for URL: https://1.1.1.1/api/count
Code:
public class AnotherDemo {
static {
//for localhost testing only
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){
public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("localhost")) {
return true;
}
return false;
}
});
}
public static void main(String[] args) throws Exception{
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
String urlString = "https://1.1.1.1/api/count";
String username = "admin";
String password = "admin";
String usercredentials = username+":admin"+password;
String basicAuth = "Basic"+ new String (new Base64().encode(usercredentials.getBytes()));
// pass encoded user name and password as header
URL url = new URL(urlString);
// URLConnection conn = url.openConnection();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Basic " + basicAuth);
conn.setRequestProperty("Accept", "application/json");
BufferedReader r = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String line = r.readLine();
while (line != null) {
System.out.println(line);
line = r.readLine();
}
}
}
Can someone tell me what I'm doing wrong?
If I use POSTMAN, everything works fine! I get the JSON!
Thanks,
R
Managed to resolve this question. These are the issues:
This line needs to be corrected and also
String usercredentials = username+":admin"+password;
String basicAuth = "Basic"+ new String (new Base64().encode(usercredentials.getBytes()));
to
String usercredentials = username+":"+password;
String basicAuth = "Basic"+ new String (new Base64().encode(usercredentials.getBytes()));
Also, for the issues with SSL handler or this exception,
com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Please add the following LOC:
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
/*
* end of the fix
*/
I'm building an application that needs to login to a certain page and make a navigation. I can login, provided that the response contains a string that identifies it. But when I navigate to the second page, I can't see the page as a logged user, only as anonymous.
I'll provide my code:
import java.net.*;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
import java.io.*;
import java.util.*;
public class PostTest {
static HttpsURLConnection conn = null;
static String sessionId = null;
private static class DefaultTrustManager implements X509TrustManager {
#Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
#Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
public static void main(String[] args) {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
SSLContext.setDefault(ctx);
String data = URLEncoder.encode("txtUserName", "UTF-8") + "=" + URLEncoder.encode(/*username*/, "UTF-8");
data += "&" + URLEncoder.encode("txtPassword", "UTF-8") + "=" + URLEncoder.encode(/*password*/", "UTF-8");
data += "&" + URLEncoder.encode("envia", "UTF-8") + "=" + URLEncoder.encode("1", "UTF-8");
connectToSSL(/*login url*/);
//throws java.lang.IllegalStateException: Already connected
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
String resposta = "";
while((line = rd.readLine()) != null) {
resposta += line + "\n";
}
System.out.println("valid login -> " + resposta.contains(/*string that assures me I'm looged in*/));
connectToSSL(/*first navigation page*/);
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while((line = rd.readLine()) != null) {
System.out.println(line);
}
} catch(Exception e) {
e.printStackTrace();
}
}
private static void connectToSSL(String address) {
try {
URL url = new URL(address);
conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
if(sessionId == null) {
sessionId = conn.getHeaderField("Set-Cookie");
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
Any further information, just ask.
In connectToSSL, you are opening a new connection each time. In second connection, it will not have any attribute from first connection.
You may want to set get some token/cookie value after fist login connection and use the same in subsequent calls by e.g.
After first connection:
String sessionId = conn.getHeaderField("Set-Cookie");
In subsequent connections:
conn.setRequestProperty("Cookie", sessionId );
Take a look at the Apache Commons project HttpClient. It will help you do what you are trying to accomplish. You need sometime much more complex than a URL class. It needs to maintain a lot of information to go from one authentication request to subsequent authenticated requests.
The site you're accessing probably uses cookies to identify logged in sessions. You'll need to save cookies set on the first request and send them on subsequent requests.
If you're using HttpsUrlConnection, see Cookie Management and java.net.CookieManager. Another choice would be Apache HttpComponents which do cookie management by default.
http is a stateless protocol.
to retain state( sessions) store the cookies received from the server.
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
send them to server in subsequent requests
for (String cookie : cookies) {
//remove expires and path from cookie
String cookieValue=cookie.substring(0, cookie.indexOf(';');
conn.addRequestProperty("Cookie",cookieValue);
}
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);