How to get cookies from HTTP response performed via Endpoint method? - java

I am trying to create an endpoint method, which is supposed to log me in to a different system and return the authorization cookie's value for further use in my application. Even though my method successfully logs me to the system (I checked the response data), i cannot retrieve the cookie from header files of the response. This is the bean's method called from endpoint method.
public String login (String password, String name) {
String urlParameters = "destination=" + MAILBOX_URL_SUFFIX + "&credential_0=" + name +
"&credential_1=" + password + "&login=Prihl%E1si%BB+sa";
URL url = null;
// ***************** login ***********************
try {
URI uri = new URI("https", "is.stuba.sk", "/system/login.pl", null);
url = uri.toURL();
} catch (Exception e) {
e.printStackTrace();
}
HttpURLConnection con = null;
try {
con =(HttpURLConnection) url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
appendRequestHeader(con);
//Send post request
con.setDoOutput(true);
DataOutputStream wr = null;
try {
wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
con.connect();
con.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
String cookie = "default";
String headerName=null;
for (int i=1; (headerName = con.getHeaderFieldKey(i))!=null; i++) {
cookie.concat(con.getHeaderField(i));
}
return cookie;
}
EDIT: the method returns "default" all the time, none Set-Cookie, nor the other cookies
Before, when i was not running the method from server-side the code started with
CookieManager manager = new CookieManager();
manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(manager);
... and instead of using con.headerField i used this, to successfully get my cookie.
return manager.getCookieStore().getCookies().get(0).getValue();
However CookieManager is blacklisted for Google Cloud Endpoints and i cannot retrieve the cookie any other way :(
Any suggestions? Thank you!

Related

Java Android FCM sending message to user Server returned HTTP response code

I did this :
public class PushNotifictionHelper {
public final static String AUTH_KEY_FCM = "AIzaSyD63pfTvnwhe9WVuIe.........";
public final static String API_URL_FCM = "https://fcm.googleapis.com/fcm/send";
public static String sendPushNotification(String deviceToken)
throws IOException, JSONException {
String result = "";
URL url = new URL(API_URL_FCM);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "key=" + AUTH_KEY_FCM);
conn.setRequestProperty("Content-Type", "application/json");
JSONObject json = new JSONObject();
json.put("to", deviceToken.trim());
JSONObject info = new JSONObject();
info.put("title", "notification title"); // Notification title
info.put("body", "message body"); // Notification
// body
json.put("notification", info);
try {
OutputStreamWriter wr = new OutputStreamWriter(
conn.getOutputStream());
wr.write(json.toString());
wr.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
result = "OK";
} catch (Exception e) {
e.printStackTrace();
result = "BAD";
}
System.out.println("GCM Notification is sent successfully");
return result;
}
public static void main(String [] args){
try {
PushNotifictionHelper.sendPushNotification("ep51x3Ckmig:APA91bG4PdoJC7zGlV0JPmCA49jmqJCkeSPH1QzF9byxdH1nRlFOVyAi9ppO2ygoSpp8s44o1oGO8n-HCJDB_oZAZ6WCwFD2a9yAFmKIpKhmPXakeLf-ktqPnzwf-GFziv7_nMdVPIci");
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
And when I run this in console I see
java.io.IOException: Server returned HTTP response code: 401 for URL: https://fcm.googleapis.com/fcm/send
an AUTH_KEY_FCM I get from web from this:
Klucz interfejsu Web API AIzaSyD63pfTvnwhe9WVuIe.........
The 401 error refers to an Authentication error. From the docs:
The sender account used to send a message couldn't be authenticated. Possible causes are:
Authorization header missing or with invalid syntax in HTTP request.
Invalid project number sent as key.
Key valid but with FCM service disabled.
Request originated from a server not whitelisted in the Server key IPs.
Check that the token you're sending inside the Authentication header is the correct Server key associated with your project. See Checking the validity of a Server key for details.
When using FCM, you should always make use of the Server Key (not the Web API Key) seen in the Cloud Messaging Tab in your Firebase Console.

Https connection Android with Http authentication

I want to make a HTTPS connection with a webservice in Android Studio but it doesn't work with the code that I have written. I get a FileNotFound Exception.
My URL is working in the browser.
And response code is 400.
This is my code:
protected Void doInBackground(String... params) {
String https_url = "HERE MY HTTPS URL";
URL url;
try {
url = new URL(https_url);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
String userPassword = "USERNAME" + ":" + "PASSWORD";
String encoding = new String(Base64.encode(userPassword.getBytes(), Base64.DEFAULT));
con.setRequestProperty("Authorization", "Basic " + encoding);
con.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
con.setRequestProperty("Accept","*/*");
//dumpl all cert info
print_https_cert(con);
//dump all the content
print_content(con);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Someone who can help me out?

Using Java (HttpURLConnection) to authenticate to Restheart (for Mongodb)

I am using restheart to provide a restful interface to mongodb. The interface is set up and running and provides the correct answer if a GET request is sent through Chrome. However if I use the following java code using a HttpURLConnection I get a 201 response with no content.
try {
videos = new URL("http://www.example.com:8080/myflix/videos");
} catch (Exception et) {
System.out.println("Videos URL is broken");
return null;
}
HttpURLConnection hc = null;
try {
hc = (HttpURLConnection) videos.openConnection();
String login="admin:admin";
final byte[] authBytes = login.getBytes(StandardCharsets.UTF_8);
final String encoded = Base64.getEncoder().encodeToString(authBytes);
hc.addRequestProperty("Authorization", "Basic "+encoded);
hc.setDoInput(true);
hc.setDoOutput(true);
hc.setUseCaches(false);
hc.setRequestMethod("GET");
hc.setRequestProperty("Accept-Encoding", "gzip, deflate, sdch");
hc.setRequestProperty("Content-Type", "application/json");
hc.setRequestProperty("Accept", "application/json,text/html,application/hal+json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*");
} catch (Exception et) {
System.out.println("Can't prepare http URL con");
return (null);
}
BufferedReader br = null;
try {
OutputStreamWriter writer = new OutputStreamWriter(
hc.getOutputStream());
} catch (Exception et) {
System.out.println("Can't get reader to videos stream");
}
String inputLine;
String sJSON = null;
try {
int rc = hc.getResponseCode();
What is the correct way to authenticate using Java to the resthert interface? (Details on the restheart authentication is here Restheart authentication
I made few changes (look for inline comments starting with <==) and it works:
The way you generate the authentication request header is correct. When I run your code I actually got 415 Unsupported Media Type, that went away commenting out hc.setDoOutput(true). A GET is a input operation, in fact you were also trying to get an OutStream from the connection: you need to get an InputStream actually.
URL url;
try {
url = new URL("http://127.0.0.1:8080/test/huge");
} catch (Exception et) {
System.out.println("Videos URL is broken");
Assert.fail(et.getMessage());
return;
}
HttpURLConnection hc = null;
try {
hc = (HttpURLConnection) url.openConnection();
String login = "admin:admin";
final byte[] authBytes = login.getBytes(StandardCharsets.UTF_8);
final String encoded = Base64.getEncoder().encodeToString(authBytes);
hc.addRequestProperty("Authorization", "Basic " + encoded);
System.out.println("Authorization: " + hc.getRequestProperty("Authorization"));
hc.setDoInput(true);
//hc.setDoOutput(true); <== removed, otherwise 415 unsupported media type
hc.setUseCaches(false);
hc.setRequestMethod("GET");
hc.setRequestProperty("Accept-Encoding", "gzip, deflate, sdch");
hc.setRequestProperty("Accept", "application/json,text/html,application/hal+json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*");
} catch (Exception et) {
System.out.println("Can't prepare http URL con");
}
System.out.println(hc.toString());
BufferedReader br = null;
try {
InputStreamReader reader = new InputStreamReader(hc.getInputStream()); // <== the request is a GET, data is in input
} catch (Exception et) {
System.out.println("Can't get reader to videos stream");
}
int rc = hc.getResponseCode();
System.out.println("response code: " + rc);
System.out.println("response message: " + hc.getResponseMessage());
Assert.assertEquals(200, rc);

HttpURLConnection 403 response after 200

Ok so I'm working on an app with 2 activities.
Let's call the 1st one LoginActivity which appears on top of my MainActivity. Also, I have a class SenderReceiver which extends AsyncTask that takes care of the connection to my https server.
The 1st time I call SenderReceiver from my LoginActivity, everything works fine & I get a 200 response & I'm able to use the JSON retrieved.
After that, the LoginActivity finishes & returns a result to the MainActivity. This is when I know I'm logged in & I can proceed.
Now whenever I execute SenderReceiver to get other information, I get the 403 response with a java.io.FileNotFoundException: https://url_of_my_server. But if I call the login again, it works.
Below is the SenderReceiver code snippet which connects to the server.
I'm also connecting to the same server on the iOS version of the app & never have issues with subsequent calls after the login.
Now this is my 1st time using https connections & such, I'm not really sure how it works on Android so I must be missing something or doing something wrong.
#Override
protected Boolean doInBackground(Object... params) {
frag = (Fragment)params[0]; // For later
addedParams = (List<NameValuePair>)params[1];
postPage = (String)params[2];
InputStream is = null;
try {
URL url = new URL(Constants.kWebService);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setReadTimeout(15000);
conn.setConnectTimeout(20000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
//conn.setDoInput(true);
conn.setRequestProperty("CONTENT_TYPE", "application/json");
conn.setRequestProperty("X-requested-with", "XMLHttpRequest");
String base64EncodedCredentials = "Basic " + Base64.encodeToString((Constants.kHTTPSUser+":"+Constants.kHTTPSPass).getBytes(), Base64.NO_WRAP);
conn.setRequestProperty("Authorization", base64EncodedCredentials);
String param = "page="+postPage+"&";
for(int i = 0; i < addedParams.size(); i++) {
String and = (i < addedParams.size()-1)? "&": "";
param += addedParams.get(i).getName()+"="+ URLEncoder.encode(addedParams.get(i).getValue(), "UTF-8")+and;
}
conn.setFixedLengthStreamingMode(param.getBytes().length);
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.close();
// Starts the query
conn.connect();
int responseCode = conn.getResponseCode();
is = conn.getInputStream();
// Convert the InputStream into a string
responseSTR = Constants.inputStreamToString(is).toString();
return true;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} catch (ProtocolException pe) {
Constants.Log("Protocol Exception:"+pe.getMessage());
} catch (IOException io) {
Constants.Log("IO Exception:"+io.getMessage());
io.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException io) {
Constants.Log("is.close IO Exception:"+io.getMessage());
}
}
}
return false;
}
Fixed it!
All I had to do was to set the cookie header with:
conn.setRequestProperty("Cookie", Constants.kCookies);
& retrieve that cookie after the response in order to set it with:
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
if(cookies != null) {
Constants.kCookies = cookies.get(0);
}
That way in the initial HttpURLConnection connections (i.e:login) the cookie is empty & not needed. Once a connection is successful (after "login") it receives the cookie & sets it.
After that, any subsequent connection sends that cookie as part of the header.
The updated method below:
#Override
protected Boolean doInBackground(Object... params) {
frag = (Fragment)params[0];
addedParams = (List<NameValuePair>)params[1];
postPage = (String)params[2];
InputStream is = null;
try {
URL url = new URL(Constants.kWebService);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setReadTimeout(15000);
conn.setConnectTimeout(20000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
//conn.setDoInput(true);
conn.setRequestProperty("CONTENT_TYPE", "application/json");
conn.setRequestProperty("X-requested-with", "XMLHttpRequest");
String base64EncodedCredentials = "Basic " + Base64.encodeToString((Constants.kHTTPSUser+":"+Constants.kHTTPSPass).getBytes(), Base64.NO_WRAP);
conn.setRequestProperty("Authorization", base64EncodedCredentials);
// Get the cookie from my Constants file & set it, Constants.kCookies is a static String
conn.setRequestProperty("Cookie", Constants.kCookies);
String param = "page="+postPage+"&";
for(int i = 0; i < addedParams.size(); i++) {
String and = (i < addedParams.size()-1)? "&": "";
param += addedParams.get(i).getName()+"="+ URLEncoder.encode(addedParams.get(i).getValue(), "UTF-8")+and;
}
conn.setFixedLengthStreamingMode(param.getBytes().length);
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.close();
// Starts the query
conn.connect();
int responseCode = conn.getResponseCode();
Constants.Log("The response code is: " + responseCode);
is = conn.getInputStream();
// Retrieve the cookie from the response & if not null save it to Constants.kCookies
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
if(cookies != null) {
Constants.kCookies = cookies.get(0);
}
// Convert the InputStream into a string
responseSTR = Constants.inputStreamToString(is).toString();//readIt(is, len);
return true;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} catch (ProtocolException pe) {
Constants.Log("Protocol Exception:"+pe.getMessage());
} catch (IOException io) {
Constants.Log("IO Exception:"+io.getMessage());
io.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException io) {
Constants.Log("is.close IO Exception:"+io.getMessage());
}
}
}
return false;
}

Parse.com REST API Error Code 400: Bad Request from Java HTTP Request to Cloud Function

I have a string that I am trying to send to a Parse.com cloud function. According to the REST API documentation (https://www.parse.com/docs/rest#general-requests), it must be in json format, so I made it into a json object and converted it to a string to append to the end of the http request url.
JSONObject jsonParam = new JSONObject();
jsonParam.put("emailId", emailId);
String urlParameters = jsonParam.toString();
Then I send the request as so, in my attempt to match their cURL code example as Java code:
con.setDoOutput(true);
DataOutputStream wr = null;
wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
Nonetheless, I receive a returned error code of 400 with error message "Bad Request", which I believe to be caused by unrecognizable parameters being sent to the cloud function. None of the other errors in my code trigger. Yet I verified through console logs that emailId is a normal string and the resulting JSON object, as well as its .toString() equivalent comes out as a proper string reading of a JSON object. Also this worked for another function I have in which I am creating an object in my Parse database. So why would it not work here?
Here is the full function for reference and context:
private void sendEmailWithParse(String emailId) throws IOException {
String url = "https://api.parse.com/1/functions/sendEmailNow";
URL obj = new URL(url);
HttpsURLConnection con = null;
try {
con = (HttpsURLConnection) obj.openConnection();
} catch (IOException e) {
System.out.println("Failed to connect to http link");
e.printStackTrace();
}
//add request header
try {
con.setRequestMethod("POST");
} catch (ProtocolException e) {
System.out.println("Failed to set to POST");
e.printStackTrace();
}
con.setRequestProperty("X-Parse-Application-Id", "**************************************");
con.setRequestProperty("X-Parse-REST-API-Key", "************************************************");
con.setRequestProperty("Content-Type", "application/json");
JSONObject jsonParam = new JSONObject();
jsonParam.put("emailId", emailId);
System.out.println("parameter being sent to cloud function: " + jsonParam);
System.out.println("parameter being sent to cloud function as string: " + jsonParam.toString());
String urlParameters = jsonParam.toString();
// Send post request
con.setDoOutput(true);
DataOutputStream wr = null;
try {
wr = new DataOutputStream(con.getOutputStream());
} catch (IOException e1) {
System.out.println("Failed to get output stream");
e1.printStackTrace();
}
try {
wr.writeBytes(urlParameters);
} catch (IOException e) {
System.out.println("Failed to connect to send over Parse object as parameter");
e.printStackTrace();
}
try {
wr.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
wr.close();
} catch (IOException e) {
System.out.println("Failed to connect to close datastream connection");
e.printStackTrace();
}
int responseCode = 0;
try {
responseCode = con.getResponseCode();
} catch (IOException e) {
System.out.println("Failed to connect to get response code");
e.printStackTrace();
}
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
System.out.println("Response message: " + con.getResponseMessage());
}
I solved the problem by using the HttpRequest external library. It gave me better control of the request and made for easier debugging of the problem. The server was receiving the request just fine, the problem was with the JSON encoding. Rather than putting the JSON object as a parameter in the request, I inserted it into the body of the http request and encoded it in UTF-8.
In the end, this is the code that worked:
String url = "https://api.parse.com/1/functions/sendEmailNow";
URL obj = new URL(url);
//Attempt to use HttpRequest to send post request to parse cloud
HttpRequest request = HttpRequest.post(obj).contentType("application/json");
request.header("X-Parse-Application-Id", "**************************");
request.header("X-Parse-REST-API-Key", "********************");
JSONObject jsonParam = new JSONObject();
jsonParam.put("emailId", emailId);
request.send(jsonParam.toString().getBytes("UTF8"));
if (request.ok())
System.out.println("HttpRequest WORKED");
else
System.out.println("HttpRequest FAILED " + request.code() + request.body());

Categories

Resources