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
Related
hi all i use this code to connect https and its work fine on my pc but when i upload to my server dont work
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
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1964)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
at mehritco.ir.connection.URLConnection.read(URLConnection.java:38)
at mehritco.ir.cortexclient.objects.invoice.Price.setExchangeRate(Price.java:42)
and this log file dont show at local pc!
here the my code for connect to https/ssl
public String readLinkInJson(String url, String data) throws MalformedURLException, IOException {
URL obj = new URL(url);
System.out.println(data);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
con.setHostnameVerifier(hv);
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setDoOutput(true);
// For POST only - START
try (OutputStream os = con.getOutputStream()) {
os.write(data.getBytes("UTF-8"));
os.flush();
}
// For POST only - END
String inputLine;
StringBuilder response = new StringBuilder();
int responseCode = con.getResponseCode();
if(responseCode >= 400){
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
}
}else{
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getErrorStream()))) {
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
}
}
return response.toString();
}
so what can i do?
please help me to find right code...
i found my answer!
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
#Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
#Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (GeneralSecurityException e) {
}
add this code befor make url object.
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"));
I'm trying to issue a post request in the next manner:
I use Apache's HttpClient 3.1
I use encoding "application/x-www-form-urlencoded"
The URL I use starts with https
this is the code I try to run:
public static String httpsPost(String url, String body, String mediaType, String encoding) {
disableCertificateValidation();
HttpClient client = new HttpClient();
StringRequestEntity requestEntity = new StringRequestEntity(body, mediaType, encoding);
PostMethod method = new PostMethod(url);
method.setRequestEntity(requestEntity);
client.executeMethod(method);
}
public static void disableCertificateValidation() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}};
// Ignore differences between given hostname and certificate hostname
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hv);
} catch (Exception e) {}
}
Upon executing executeMethod I catch:
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
I tried to disable certificate validation but it did not help.
If you want to ignore the certificate all together then take a look at the answer here Ignore self-signed ssl cert using Jersey Client
Although this will make your app vulnerable to man-in-the-middle attacks.
You can instead of this try adding the certificate to your java store as a trusted cert. This site may be helpful. http://blog.icodejava.com/tag/get-public-key-of-ssl-certificate-in-java/
Here's another answer showing how to add a cert to your store. Java SSL connect, add server cert to keystore programatically
The key is
KeyStore.Entry newEntry = new KeyStore.TrustedCertificateEntry(someCert);
ks.setEntry("someAlias", newEntry, null);`
I refactored my old code to handle https. Now it works and looks like this:
public static String httpsPost(String url, String body, String mediaType, String encoding) {
SSLContext ctx;
ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager()}, new SecureRandom());
SSLContext.setDefault(ctx);
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
URL serverUrl = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) serverUrl.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.connect();
OutputStreamWriter post = new OutputStreamWriter(con.getOutputStream());
post.write(body);
post.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
String content = "";
while ((inputLine = in.readLine()) != null) {
content += inputLine;
}
post.close();
in.close();
return content;
}
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.