i'm trying to read a website as html using the following code(i.e < html >< body >.....< /body >< /html >, but i need to provide authentication credentials, i have tried providing using java.net.Authenticator but it still dosen't seem to work, (if i enter www.google.com it works since no authentication is required)(I wish to implement this code in my android application)
package com.test.connection;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.net.HttpURLConnection;
public class Authenticate {
String username="myuser";
String password="mypass";
URL url=null;
String webHtmlData=null;
public static void main(String[] args) {
Authenticate au=new Authenticate();
au.setConnectionToWS("https://mysite/New/"); //if i enter www.google.com it works
}
public void setConnectionToWS(String inpUrl){
Authenticator myAuth = new Authenticator()
{
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(username, password.toCharArray());
}
};
Authenticator.setDefault(myAuth);
try {
url = new URL(inpUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();//on debugging the code fails on this line.
} catch (IOException e) {
e.printStackTrace();
}
try {
InputStream in = null;
try {
in = new BufferedInputStream(urlConnection.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
finally {
webHtmlData=readStream(urlConnection);
System.out.println(webHtmlData);
System.out.println("Done!!!");
}
}
//read data as a browser
private String readStream(HttpURLConnection urlConnection) {
StringBuffer response = null;
try {
BufferedReader is =
new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String inputLine;
response = new StringBuffer();
while ((inputLine = is.readLine()) != null) {
response.append(inputLine);
}
is.close();
}
catch (Exception e) {
e.printStackTrace();
}
return response.toString();
}
}
i tried debugging and the code shows the following error at line urlConnection.connect()
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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)
at com.test.connection.Authenticate.setConnectionToWS(Authenticate.java:48)
at com.test.connection.Authenticate.main(Authenticate.java:23)
Caused by: 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.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
... 13 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 19 more
Am i not providing the credentials properly???
on passing the url as www.google.com i get the output as
Google
Done!!!
i need to get the same on passing my url which requires authentication,(on entering my url on a browser a popup is shown to enter username and password which on submitting i am directed to the page)
Answer
If you have a self-signed certificate, either you should import your self-signed certificate into java truststore or easy way add below code to bypass certificate validation. In production it is better to use a trusted certificate.
Add following code after Authenticator.setDefault(myAuth); line.
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
try {
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (Exception ex) {
ex.printStackTrace();
}
Finally change this line
urlConnection = (HttpURLConnection) url.openConnection();
to (use HttpsUrlConnection)
urlConnection = (HttpsURLConnection) url.openConnection();
No comments:
Post a Comment