-1

I have some code of ruby http post for hitting the API, but right now I need to convert it into java or groovy

this is my code on ruby

def loginWithEmailPassword(str_email, str_password)
  uri = URI(url)

  req = Net::HTTP::Post.new(uri)
  req['Content-Type'] = 'application/json'
  req['x-request-id'] = "xyz-#{SecureRandom.hex}"
  req['user-agent'] = 'xyz'

  req.body = { 
  email: str_email, 
  password: str_password
  }.to_json

  Net::HTTP.start(uri.host, uri.port,
    :use_ssl => uri.scheme == 'https',
    :verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
    response = http.request(req) # Net::HTTPResponse object

    if(response.code != '200')
      puts response.body # Show response body
      raise ("ERROR: login error... error code #{response.code}")
    end
    return response.body
  end
end

This are my code on java

    def loginApiWithEmailPassword(String sEmail, String sPassword){
            URL url = new URL(m_url + "/login/password");
            JSONObject json = new JSONObject();
            json.put("email", sEmail);
            json.put("password", sPassword);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
// set header
            conn.setRequestMethod("POST")
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("user-agent", aaa);
            conn.setRequestProperty("x-request-id", getSecureRandom(s))
            conn.setDoOutput(true);
            conn.setDoInput(true);

            OutputStream os = conn.getOutputStream();

            os.write(json.toJSONString().getBytes());
            os.close();

            // read the response
            InputStream input = new BufferedInputStream(conn.getInputStream());
            String result = org.apache.commons.io.IOUtils.toString(input, "UTF-8");
            JSONObject jsonObject = new JSONObject(result);


            input.close();
            conn.disconnect();

            return jsonObject;
        }

I have tried to convert it into java but failed, stuck on error "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"

And unable to continue to check the next function, may anyone able to help me to complete the http post for java or groovy

hakuya
  • 49
  • 5

2 Answers2

0

You can make use of solution mentioned here. As per this solution you can implement a method doTrustToCertificates() and then call this method before setting the connection:

public void doTrustToCertificates() throws Exception {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        return;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        return;
                    }
                }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) {
                    System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'.");
                }
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }

Call doTrustToCertificates() before trying to connect to URL as shown below:

    public void loginApiWithEmailPassword(String sEmail, String sPassword){
            URL url = new URL(m_url + "/login/password");
            JSONObject json = new JSONObject();
            json.put("email", sEmail);
            json.put("password", sPassword);
            doTrustToCertificates();/
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
// set header
            conn.setRequestMethod("POST")
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("user-agent", aaa);
            conn.setRequestProperty("x-request-id", getSecureRandom(s))
            conn.setDoOutput(true);
            conn.setDoInput(true);

            OutputStream os = conn.getOutputStream();

            os.write(json.toJSONString().getBytes());
            os.close();

            // read the response
            InputStream input = new BufferedInputStream(conn.getInputStream());
            String result = org.apache.commons.io.IOUtils.toString(input, "UTF-8");
            JSONObject jsonObject = new JSONObject(result);


            input.close();
            conn.disconnect();

            return jsonObject;
        }
Yug Singh
  • 3,112
  • 5
  • 27
  • 52
  • Hi Yug thanks for answering, I have tried your code but I got an error "FAILED because (of) org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'blabla.RestApi$2@c7a977f' with class 'blabla.RestApi$2' to class 'oracle.net.jndi.TrustManager', any clue? – hakuya Aug 30 '18 at 04:33
0

So, your main problem is that Java does not trust your certificate out of the box. The solution mentioned by Yug Singh to change the TrustManager should work if done right, but it is IMHO not very clean.

The better solution is to get the certificate you want to trust (normally you can download it via your browser by clicking on the small lock-symbol in the URL) and add it to the java trustStore of your machine or if you only want to trust it for this piece of code, create a new trustStore and instruct java to use this trustStore.

Information on how to use a trsutStore can be found in several locations like the oracle docs: https://docs.oracle.com/cd/E19509-01/820-3503/6nf1il6er/index.html and https://docs.oracle.com/cd/E19830-01/819-4712/ablqw/index.html

basically, you create the trustStore via

keytool -import -file theCertificateToBeTrusted.cert -alias justSomeAlias -keystore myTrustStore

and you isntruct java to use this keyStore by starting it with some extra parameters

-Djavax.net.ssl.trustStore=/path/toYour/myTrustStore

(I think you don't need to set a password on the trustStore for this use case)

also have a look at this SO answer: Using browser's certificate in java program

rdmueller
  • 10,742
  • 10
  • 69
  • 126