Java - Accessing Secure HTTPS Third Party API - java

I am editing a Java application and trying to access a secure third party API. There are two String variables that need to be passed, and ID and a token for the secure access. The code below is using Maven. I am trying to tweak the code for just Java.
public class JavaApiStreaming {
public static void main (String[]args) throws IOException {
HttpClient httpClient = HttpClientBuilder.create().build();
try {
// Set these variables to whatever personal ones are preferred
String domain = "https://stream-fxpractice.oanda.com";// trying to access this api
String access_token = "ACCESS-TOKEN"; //using this token
String account_id = "1234567"; //using this ID
String instruments = "EUR_USD,USD_JPY,EUR_JPY";
// This is the part of the code I am trying to edi. to my knowledge this is //maven coding
HttpUriRequest httpGet = new HttpGet(domain + "/v1/prices?accountId=" + account_id + "&instruments=" + instruments);
httpGet.setHeader(new BasicHeader("Authorization", "Bearer " + access_token));
System.out.println("Executing request: " + httpGet.getRequestLine());
HttpResponse resp = httpClient.execute(httpGet);
HttpEntity entity = resp.getEntity();
if (resp.getStatusLine().getStatusCode() == 200 && entity != null) {
InputStream stream = entity.getContent();
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
while ((line = br.readLine()) != null) {
Object obj = JSONValue.parse(line);
JSONObject tick = (JSONObject) obj;
// unwrap if necessary
if (tick.containsKey("tick")) {
tick = (JSONObject) tick.get("tick");
}
// ignore heartbeats
if (tick.containsKey("instrument")) {
System.out.println("-------");
String instrument = tick.get("instrument").toString();
String time = tick.get("time").toString();
double bid = Double.parseDouble(tick.get("bid").toString());
double ask = Double.parseDouble(tick.get("ask").toString());
System.out.println(instrument);
System.out.println(time);
System.out.println(bid);
System.out.println(ask);
}
}
} else {
// print error message
String responseString = EntityUtils.toString(entity, "UTF-8");
System.out.println(responseString);
}
} finally {
httpClient.getConnectionManager().shutdown();
}
}
}

It seems like you're asking how to use the standard library instead of any dependencies and encode the account_id/access token as part of basic auth header. I would suggest using HttpURLConnection. It's included as part of the Java standard library. Try the following:
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
String encoded = Base64.encode(account_id+":"+access_token);
connection.setRequestProperty("Authorization", "Basic "+encoded);

Related

Posting JSON to REST API from Java Servlet

I'm having issues trying to send over a JSON string to a REST API. Long story short, I'm taking user input in a form, sending it over to a java servlet to validate and work with it a bit, and then trying to send it to an endpoint.
I have the following method being called on in my doPost method in my servlet, I am using printwriter pw to be able to read back data being returned in my response in the browser console at this point.
String jsonData = //JSON STRING HERE\\
String username = //USERNAME\\
String password = //PASSWORD\\
String endpointURL = //ENDPOINT URL HERE\\
pw.println(sendJson(jsonData, username, password));
private String sendJSON(String jsonData, String usrname, String usrpass) {
try {
String auth = usrname + ":" + usrpass;
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8));
String authHeaderValue = "Basic " + new String(encodedAuth);
URL url = new URL(endpointURL);
HttpURLConnection http = (HttpURLConnection)url.openConnection();
http.setConnectTimeout(5000);
http.setReadTimeout(5000);
http.setRequestMethod("POST");
http.setRequestProperty("Content-Type", "application/json; utf-8");
http.setRequestProperty("Authorization", authHeaderValue);
http.setDoOutput(true);
//POST Json to URL using HttpURLConnection
//try(OutputStream os = http.getOutputStream()) {
OutputStream os = http.getOutputStream();
byte[] input = jsonData.getBytes("utf-8");
os.write(input, 0, input.length);
//}
/*String responseBody;
try(BufferedReader br = new BufferedReader(
new InputStreamReader(http.getInputStream(), "utf-8"))) {
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
//System.out.println(response.toString());
responseBody = response.toString();
return responseBody;
}
return responseBody;*/
BufferedReader in = new BufferedReader(
new InputStreamReader(http.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
} catch (IOException e) {
return e.toString();
}
}
}
I was having issues with the try's so I rewrote it to try and just get functionality right away first. Right now I'm receiving "java.io.IOException: Server Returned HTTP response code: 500 for URL: //URL HERE\"
Would anybody have any tips to point me in the right direction? I feel like I'm just missing like a small piece of the puzzle at this point, and I'm having a hard time finding any tutorials showing what it is that I'm trying to do. Thank you so much to anyone for any tips/pointers!
Made sure I was able to authenticate and that wasn't the issue by just connecting and returning:
int statusCode = http.getResponseCode();
String statusCodeString = Integer.toString(statusCode);
return statusCodeString;
This worked fine, received 403 response when setting wrong password/username and 400 response when I change to correct.
I attempted using HttpClient as well instead, but was having issues trying to get that to work at all. I also had an error earlier with week trying to do this with a certificate error, but after reimporting the cert to my cacerts file this was resolved (unrelated to this issue I believe).

How to use httpclient 4.3.6 to invoke DCTM 7.1 REST API?

I am looking to interact with a Documentum Repository using their REST API. I would like to use the http-client 4.3 jars to perform this interaction.
I was hoping someone might have a sample that would help point me in the correct direction on how to interact with DCTM.
I am having trouble finding a clear and simple example of how to do this.
Thanks
I know it is a bit late to answer this question. But i want to answer to help those who still need a code for making requests to the rest api. Here is a full example of sending a post request to the rest api for starting a workflow.
For other needs you can check the Document called Documentum xCP Rest Services provided by EMC : https://support.emc.com/docu52500_Documentum-xCP-REST-Services-2.1-Development-Guide.pdf?language=en_US&request=akamai and compare with this example, change it according to it's needs.
UPDATE:
Also if you are not using xcp here is the Documentation for rest api without it emc.com/collateral/TechnicalDocument/docu57895.pdf
You can also check my answer here How can I use REST to copy an object in Documentum 7.x for geting object data and content from the rest api ( without xcp )
String strResponse = "";
String process_id = "system_name of the process you want to start";
String url = "Your App Url Here/processes/" + process_id;
String json = "{"+
"\"run-stateless\" : \"false\","+
"\"data\" :"+
" { "+
" \"variables\" : "+
" { \"Variable name\" : \"Variable value\" } "+
" } "+
"}";
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
BufferedReader rd = null;
CloseableHttpResponse cls = null;
try {
HttpPost request = new HttpPost(url);
// set timeouts as you like
RequestConfig config = RequestConfig.custom()
.setSocketTimeout(60 * 1000).setConnectTimeout(20 * 1000)
.setConnectionRequestTimeout(20 * 1000).build();
request.setConfig(config);
StringEntity params = new StringEntity(json);
request.addHeader("Accept", "application/json");
request.addHeader(
"Authorization",
"Basic "
+ com.documentum.xmlconfig.util.Base64
.encode("username here" + ":"
+ "password here"));
request.addHeader("Content-Type", "application/vnd.emc.xcp+json");
request.setEntity(params);
try {
cls = httpClient.execute(request);
HttpEntity entity = cls.getEntity();
rd = new BufferedReader(new InputStreamReader(
entity.getContent()));
String line = "";
while (line != null) {
line = rd.readLine();
strResponse += line;
}
strResponse = strResponse.trim().replace("\n", "");
String statusline = cls.getStatusLine().toString();
if (!statusline.contains("200") && !statusline.contains("201")) {
Log.write("Process is not started");
// log the strResponse or do something with it
} else {
System.out.println("Process started successfully");
}
} catch (Exception e) {
e.printStackTrace();
}
} finally {
// using commons-io-2.4.jar
IOUtils.closeQuietly(httpClient);
IOUtils.closeQuietly(cls);
IOUtils.closeQuietly(rd);
}

setting up mutual authentication client using HttpURLConnection

I have a simple http service with JSON payload I want to test with a Java test harness.
Initially I set up a client using Basic Auth which works fine; server certificate is in the trustStore and I'm supplying username/password in the code. I send the request, I get the correct response.
public static void main(String[] args) {
// TODO Auto-generated method stub
String xxxURL = new String("https://www.xxx.yyy/zzz/AdminServlet?data=");
String username = new String("username");
String password = new String("password");
String authString = new String (username+":"+password);
String apiList = new String("{\"apiVersion\":\"1.4\",\"method\":\"api.list\",\"params\":{}}"); // Create JSON string. A bit ugly
try
{
System.setProperty("javax.net.ssl.trustStore","C:\\workspace\\http_client_test\\security\\cacerts");
String jsonStr = apiList;
URL url = new URL(xxxURL + URLEncoder.encode(jsonStr, "UTF-8") );
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); // create connection object
String encoded = Base64.encodeBase64String(authString.getBytes());
httpConn.setRequestProperty("Authorization", "Basic "+encoded);
httpConn.setRequestMethod("GET");
httpConn.connect(); // open connection
BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
String temp = null;
StringBuilder sb = new StringBuilder();
while((temp = in.readLine()) != null)
{
sb.append(temp).append(" ");
}
String result = sb.toString();
System.out.println("result = " + result);
}
catch(Exception e)
{
e.printStackTrace();
}
}
I want to do the same test using mutual authentication. I have set up the keystore and truststore on both server and client, and imported the necessary certificates on each.
My problem is I cannot find out how to tell the HttpURLConnection that I want mutual certificate authentication.
I tried :
public class Test3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String xxxURL = new String("https://www.xxx.yyy/zzz/AdminServlet?data=");
String apiList = new String("{\"apiVersion\":\"1.4\",\"method\":\"api.list\",\"params\":{}}"); // Create JSON string. A bit ugly
try
{
System.setProperty("javax.net.ssl.trustStore","C:\\workspace\\http_client_test\\security\\cacerts");
System.setProperty("javax.net.ssl.trustStorePassword","changeit");
System.setProperty("javax.net.ssl.keyStore","C:\\workspace\\http_client_test\\security\\keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword","password");
String jsonStr = apiList;
URL url = new URL(netThingsURL + URLEncoder.encode(jsonStr, "UTF-8") );
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); // create connection object
String encoded = Base64.encodeBase64String(authString.getBytes());
httpConn.setRequestProperty("Authorization", "?????????"); // ????????
httpConn.setRequestMethod("GET");
httpConn.connect(); // open connection
BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
String temp = null;
StringBuilder sb = new StringBuilder();
while((temp = in.readLine()) != null)
{
sb.append(temp).append(" ");
}
String result = sb.toString();
System.out.println("result = " + result);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
What should I have here : httpConn.setRequestProperty("Authorization", "?????????"); I realise I may need more than just this 1 line. I tried various resources to find appropriate values but drew a blank. I tried various intuitive arguments but get a '401' error or NoSuchAlgorithException.
Any help, code, links to resources is greatly appreciated.
My problem is I cannot find out how to tell the HttpURLConnection that I want mutual certificate authentication.
You can't. You have to configure the server to ask for the client certificate. All you can do at the client is specify where the client certificate is. You can't force it to be sent. Only the server can do that.

Send data using POST to java server from Android client and get JSON response

I am completely new to Android programming. I have come across the following problem -
I want to validate the credentials of the user who uses the application. For this I want to use POST method to send the Login details to the server. From there I want to get response in JSON format. I don't know how to receive the response. I am using Java for server side programming.
P.S. I would deal with security concerns bit later.
Following is my Android code. I know it is a mess.. Please help.
HttpURLConnection connection;
OutputStreamWriter request = null;
URL url = null;
String response = null;
String parameters = "username="+mUsername+"&password="+mPassword;
try
{
url = new URL("address");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();
request = new OutputStreamWriter(connection.getOutputStream());
request.write(parameters);
request.flush();
request.close();
String line = "";
InputStreamReader isr = new InputStreamReader(connection.getInputStream());
BufferedReader reader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null)
{
sb.append(line);
}
// Response from server after login process will be stored in response variable.
response = sb.toString();
// You can perform UI operations here
Toast.makeText(this,"Message from Server: \n"+ response, 0).show();
isr.close();
reader.close();
}
catch(IOException e)
{
// Error
return -1;
}
There's an open source class you can use for just this, and you can easily browse the code to see how it works. There are actually many open source libs that do this, but the following is among the cleanest and easiest to work with in my opinion.
https://github.com/kevinsawicki/http-request/blob/master/lib/src/main/java/com/github/kevinsawicki/http/HttpRequest.java
And your code will probably look something like this:
Map<String, String> params = new HashMap<String, String>();
params.put("username", mUsername);
params.put("password", mPassword);
String response = HttpRequest.post(url).form(params).body();
EDIT
My original answer including the params map in to post method would have sent the request as a POST but the params in the url. The corrected version (form method) sends the params in the body.
You can convert your json response to a JSONObject class.
Look this app, the code is very simple.
#Override
public List<User> getRanking() {
final List<User> result = new ArrayList<User>();
String url = "http://quiz-exmo.rhcloud.com/rest/user/ranking/";
String json = HttpUtil.doGet(url);
try {
final JSONObject resultJsonObject = new JSONObject(json);
final JSONArray jsonArray = resultJsonObject.getJSONArray("users");
for (int index = 0, total = jsonArray.length(); index < total; index++) {
final JSONObject jsonObject = jsonArray.getJSONObject(index);
final User user = new User();
user.name = jsonObject.getString("name");
user.email = jsonObject.getString("email");
user.score = jsonObject.getInt("points");
result.add(user);
}
} catch (JSONException e) {
throw new RuntimeException(e);
}
return result;
}
https://github.com/exmo/equizmo-android/blob/master/maven/equizmo/src/main/java/br/gov/serpro/quiz/service/rest/UserServiceRest.java

Request to server API using Java and JSON

I have documentation of server API with several methods. The problem is that I have never used API to work with server. What I can do to do it more easy?
Part of API documentation:
Method "Login":
POST http://api.example.com/login-ajax
Parameters:
email
password
Response:
{
"success":true,
"currentUser":222,
"userData":{
"displayName":"User",
"displayAvatarId":"asjhdsasduh",
"email":"qwerty#gmail.com",
"isEmailConfirmed":"0",
"sex":"m"
}
}
The response is JSON object, but I don't know how to send request to get this response.
Help me please.
UPGRADE
I tried to use Jsoup:
Connection.Response res = Jsoup.connect("http://api.example.com/login-ajax")
.data("email", "mail#gmail.com", "password", "pass")
.method(Connection.Method.POST)
.header("Accept", "application/json")
.header("X-Requested-With", "XMLHttpRequest")
.header("X-App-Api", "1.0")
.header("X-App", "iOS")
.ignoreContentType(true)
.execute();
Document document = Jsoup.parse(res.parse().outerHtml());
System.out.println(document.text());
The response is:
{"success":false,"exception":"Exception_User","message":"\u041c\u044b \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 \u0432 \u0431\u0430\u0437\u0435 \u0442\u0430\u043a\u043e\u0435 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 \u044d\u043b. \u043f\u043e\u0447\u0442\u044b \u0438 \u043f\u0430\u0440\u043e\u043b\u044f. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0435\u0449\u0435 \u0440\u0430\u0437."}
UPGRADE 2
I also tried to use this one:
System.out.println(getJSON("http://api.example.com/login-ajax"));
public static String getJSON(String url) {
try {
URL u = new URL(url);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("POST");
c.setRequestProperty("email", "mail#gmail.com");
c.setRequestProperty("password", "pass");
c.setRequestProperty("Accept", "application/json");
c.setRequestProperty("X-Requested-With", "XMLHttpRequest");
c.setRequestProperty("X-App-Api", "1.0");
c.setRequestProperty("X-App", "iOS");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
c.setConnectTimeout(1000);
c.setReadTimeout(1000);
c.connect();
int status = c.getResponseCode();
switch (status) {
case 200:
System.out.println("200");
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
case 201:
System.out.println("201");
br = new BufferedReader(new InputStreamReader(c.getInputStream()));
sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
}
} catch (MalformedURLException ex) {
System.out.println("MalformedURLException");
} catch (IOException ex) {
System.out.println("IOException");
}
return null;
}
And the response is:
{"success":false,"exception":"Exception_Validation","message":"\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 e-mail","errors":{"email":["\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 e-mail."],"password":["\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c"]}}
As I haven't used Jsoup so far I can't give detailed information on how to use it, but I had to work with Restlet and therefore created my own JSON messages (either via org.json.JSONObject or via plain String). A post-example using Restlet would look something like this:
try
{
// create a Restlet client
ClientResource cr = new ClienResource("http://api.example.com/login-ajax");
// create the JSON message
JSONObject message = new JSONObject();
message.put("email", "mail#gmail.com");
message.put("password", "pass");
// use HTTP POST method to send the JSON message
cr.post(message, MediaType.APPLICATION_JSON);
// receive the answer - error checks omitted!
Response response = cr.getResponse();
JsonRepresentation jsonRep = new JsonRepresentation(response.getEntity());
// process the JSON response
JSONObject json = jsonRep.getJsonObject();
System.out.println("success: "+json.get("success"));
System.out.println("current user: "+json.get("currentUser"));
// extract the user data
JSONObject userData = (JSONObject)json.get("userData");
System.out.println("display name: "+userData.get("displayName"));
System.out.println("display avatar Id: "+userData.get("displayAvatarId"));
System.out.println("email: "+userData.get("email"));
System.out.println("is email confirmed: "+userData.get("isEmailConfirmed"));
System.out.println("sex: "+userData.get("sex"));
}
catch (ResourceException | JSONException ex)
{
ex.printStackTrace();
}
HTH
Consider to use an Apache HTTP Client to create a connection to your HTTP server.
Its a general-purpose library for working with HTTP requests. There are plenty resources that illustrate the usage of HTTP client, Here is an example
I admit, I've never used JSoup so I can't really comment on your example.
Hope this helps,
Mark

Categories

Resources