REST Client returns HTTP response code: 401 - java

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
*/

Related

Android : HTTPS urls are not working in Okhttp3

I am using Okhttp3 in my android application to download files. I am having problem with https urls.
I have two URLS
String url1 = "https://cbsenet.nic.in/cbsenet/PDFDEC2014/Paper%20III/D-01-3.pdf";
String url2 = "https://www.ugcnetonline.in/question_papers/June2014_paper-II/J-02-14-II.pdf";
url2 is working fine while for url1 I am getting exception
Exception in thread "main" 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 have created a sample java program to demonstrate the problem
public static void main(String[] args) throws IOException {
String url1 = "https://cbsenet.nic.in/cbsenet/PDFDEC2014/Paper%20III/D-01-3.pdf";
String url2 = "https://www.ugcnetonline.in/question_papers/June2014_paper-II/J-02-14-II.pdf";
Request request = new Request.Builder()
.url(url1)
.build();
OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
This is my solution, It works
private static OkHttpClient generateDefaultOkHttp() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
#SuppressLint("TrustAllX509TrustManager")
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
#SuppressLint("TrustAllX509TrustManager")
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
#SuppressLint("BadHostnameVerifier")
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
} catch (Exception e) {
e.printStackTrace();
}
builder.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.retryOnConnectionFailure(true);
return builder.build();
}
Since at last, you choose to trust all cers for your url1, then how could you make your url2 worked before?
BR,
Xiangbin

HttpClient https Post request fails

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;
}

I am gettin error when I call Web Service (SSL)

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.

Authenticating on a server using HTTP Commons Client

I am a complete beginner at this and I have been trying to make a connection with the server for quite some time
public class Test {
public static void main(String[] args) throws ClientProtocolException, IOException {
DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.getCredentialsProvider().setCredentials(
new AuthScope("9.5.127.34", 80),
new UsernamePasswordCredentials("root", "passw0rd"));
String url_copied_from_firebug = "https://9.5.127.34/powervc/openstack/volume/v1/115e4ad38aef463e8f99991baad1f809//volumes/3627400b-cd98-46c7-a7e2-ebce587a0b05/restricted_metadata"
HttpGet httpget = new HttpGet(url_copied_from_firebug);
HttpResponse response = httpClient.execute(httpget);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
}
}
The error which I get when I try to run the code is
Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
I have tried changing the port number from 80 to 443 but it is not working. I think I am starting with it and might be missing a lot of things. Please point me in the right direction.
Thanx in advance.
Your problem is not HTTP authentication. Your http client could not verify the ssl certificate for the server with a certificate authority - this is probably because you are using a self-signed certificate.
Look at the HttpClient documentation for instructions about how to customize your client to allow a self-signed certificate.
Here is an example of creating an HttpClient that accepts all certificates and host names - just remember to use it with servers you trust:
private DefaultHttpClient getSSLHttpClient(final URL url) throws RestClientException {
try {
final X509TrustManager trustManager = createTrustManager();
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[]{trustManager}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, createHostnameVerifier());
AbstractHttpClient base = new DefaultHttpClient();
ClientConnectionManager ccm = base.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme(HTTPS, url.getPort(), ssf));
return new DefaultHttpClient(ccm, base.getParams());
} catch (final Exception e) {
throw new RestClientException(FAILED_CREATING_CLIENT, "Failed creating http client",
ExceptionUtils.getFullStackTrace(e));
}
}
private X509TrustManager createTrustManager() {
X509TrustManager tm = new X509TrustManager() {
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkServerTrusted(final X509Certificate[] chain, final String authType)
throws CertificateException {
}
#Override
public void checkClientTrusted(final X509Certificate[] chain, final String authType)
throws CertificateException {
}
};
return tm;
}
private X509HostnameVerifier createHostnameVerifier() {
X509HostnameVerifier verifier = new X509HostnameVerifier() {
#Override
public boolean verify(final String arg0, final SSLSession arg1) {
return true;
}
#Override
public void verify(final String host, final String[] cns, final String[] subjectAlts)
throws SSLException {
}
#Override
public void verify(final String host, final X509Certificate cert)
throws SSLException {
}
#Override
public void verify(final String host, final SSLSocket ssl)
throws IOException {
}
};
return verifier;
}
First of all you must configure server.xml file.You must uncomment which line start Connector port="8443"

Java consuming REST services

I'm trying to consume a REST service using a Java client and I obtain java.net.ConnectException: Connection timed out exception.
If I'm using a web client (chrome, firefox) I'm able to retrieve the right answer.
I added in windows firewall an exception for java but this not solve my problem.
My connection is secured.
SSLContext sslContext = SSLContext.getInstance("TLS");
X509TrustManager[] xtmArray = new X509TrustManager[] { new OwnTrustManager() };
sslContext.init(null, xtmArray, new java.security.SecureRandom());
if (sslContext != null) {
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
.getSocketFactory());
}
HttpsURLConnection
.setDefaultHostnameVerifier(new ISAHostnameVerifier());
public class OwnTrustManager implements X509TrustManager{
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
public class ISAHostnameVerifier implements HostnameVerifier{
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
Business logic is:
URL url = null;
try {
url = new URL("https://16.9.1.82/xxxx/v23/rest");
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Accept", "application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
con.setRequestProperty("Accept-Encoding", "gzip,deflate,sdch");
con.setRequestProperty("Cookie", "----");
con.setRequestProperty("Host", "16.9.1.82");
con.setRequestProperty("Authorization", "Basic U1BQQ19STTFASUJNLkNPTTptYXhhZG1pbg==");
con.connect();

Categories

Resources