Why all my https request are consider in server log as POST? - java

Why all my request methods (post,get,delete) are considered as POST method? if something wrong in the code can you explain what is the problem and how to fix it?
the method has a string parameter where I change it to post/delete/get
for all request I got https error code 405 but for post I got 200.
Thank you
my code -

well, Http-Code 405 means: Method Not Allowed => your server only implemented a POST method. Until you implement another methods on the server you will not be able to call them from your client.

I have fixed this, since POST method required the body while GET and DELETE do not need the body, for Authentication I used basicauth.
if (user_name != "" || password != "")
{
if (method == "POST")
{
// write body to query
String body = "username=" + user_name + "&password=" + password;
OutputStream os = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(body);
writer.flush();
writer.close();
os.close();
}
else
{
String userpass = user_name + ":" + password;
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
connection.setRequestProperty ("Authorization", basicAuth);
InputStream in = connection.getInputStream();
}
}
// connect
connection.connect();
//results
String results = request_call_results(connection);
JSONObject json = String_toJson(results);
return json;

Related

OKTA access token using token endpoint url returns http 401 error

I am new to OKTA.
Using the below code to get the access token.. but getting 401 unauthorized error in this line
inputBuff = new BufferedReader(new
InputStreamReader(httpsClient.getInputStream()));
String oktaURL = "https://xxx.oktapreview.com/oauth2/default/v1/token";
String urlParameters = “client_id=” + clientId+“grant_type=authorization_code&redirect_uri=”+“http://:8192/app”+"&code="+oktaCode;
URL url1 = new URL(oktaURL);
StringBuffer response = null;
String output1;
log.info("The url to get the access token:"+url1.toString());
if (url1.getProtocol() != null && url1.getProtocol().startsWith("https")){
//String encodedData = DatatypeConverter.printBase64Binary((clientId + ":" + clientSecret).getBytes("UTF-8"));
//String authorizationHeaderString = "Authorization: Basic " + encodedData;
httpsClient = (HttpsURLConnection) url1.openConnection();
httpsClient.setRequestMethod("POST");
httpsClient.setRequestProperty("Accept","application/json");
httpsClient.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()));
httpsClient.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
httpsClient.setInstanceFollowRedirects(false);
log.info ("Send the POST request");
// Send post request
httpsClient.setDoOutput(true);
try (DataOutputStream opStream = new DataOutputStream(httpsClient.getOutputStream())) {
opStream.writeBytes(urlParameters);
opStream.flush();
}
inputBuff = new BufferedReader(new InputStreamReader(httpsClient.getInputStream())); // throwing 401 here.
log.info("Read from the input stream");
response = new StringBuffer();
while ((output1 = inputBuff.readLine()) != null) {
response.append(output1);
}
}
if (response != null) {
String theString = response.toString();
log.trace("Info:"+theString);
}
I could navigate to OKTA server's login page via /authorize URL and then authentication is successful and coming back to my application. Now trying to get access token. Please help how to solve this in java.
I just checked the okta log, it says the below right above the authenticate success log.
You forgot to put & after your actual client_id, so your string should look like
String urlParameters =
"client_id=" + clientId +
"&grant_type=authorization_code" +
"&redirect_uri=" + "http://:8192/app" +
"&code=" + oktaCode;
Solve the issue, there were 2 issues.
Removed client_id from urlParameters as its given in Authorization header
Removed default from /token endpoint as its not give in my /authorize endpoint.

I have given correct parameters and headers for POST method, but response code is 400

I was trying to integrate SnapChat login kit to my web application. I was able to get the authorization code from the SnapChat, but I am having trouble getting the access token.
I have done FB, Google, Instagram login integration perfectly fine, but this one I am totally lost.
I have tried to encode the parameters, change the order of headers, but all the time it gives me 400 bad request.
try {
URL url = null;
if(service.equals(APIConstants.GOOGLE))
url = new URL(SNSIdentifications.GOOGLE_TOKEN_REQUEST_URL);
else if (service.equals(APIConstants.FACEBOOK))
url = new URL(SNSIdentifications.FACEBOOK_TOKEN_REQUEST_URL);
else if (service.equals(APIConstants.INSTAGRAM))
url = new URL(SNSIdentifications.INSTAGRAM_TOKEN_REQUEST_URL);
else
url = new URL(SNSIdentifications.SNAPCHAT_TOKEN_REQUEST_URL);
conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
if(service.equals(APIConstants.SNAPCHAT)) {
// String userCredentials = URLEncoder.encode(client_id + ":" + secret, "UTF-8");
String userCredentials = client_id + ":" + secret;
byte[] data = Base64.getEncoder().encode(userCredentials.getBytes());
String authorizationHeaderBase64 = new String(data);
conn.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded" );
conn.setRequestProperty( "Authorization", "Basic " + authorizationHeaderBase64);
// conn.setRequestProperty("charset", "utf-8");
//Integer.toString(payload.getBytes(StandardCharsets.UTF_8).length)
// conn.setRequestProperty( "Content-Length", Integer.toString(payload.getBytes(StandardCharsets.UTF_8).length) );
writer = new OutputStreamWriter(conn.getOutputStream());
// writer.write(URLEncoder.encode(payload, "UTF-8"));
writer.write(params);
writer.flush();
System.out.println(conn.getResponseCode() + " " + conn.getResponseMessage() + " ");
} else {
writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(params);
writer.flush();
}
int responseCode = conn.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK) {
return new JSONObject(fetchResponse(conn));
}
} catch (IOException e) {
e.printStackTrace();
}
I should expect access token, refresh token, and expires_in values from the code above, but unfortunately it cannot, because of 400 bad request error.
I solved the problem. It turned out it was several combinations of problems.
When you are having an issue as I posted, please do check the followings:
Make sure you are using correct Client Id and Secret.
If you are adding Code Challenge and code challenge method parameters, you need to have code verifier to get access token. If you don't have these parameters, you don't need to worry about getting an access token.
When setting a header "Authorization" use base64 encode, not base16. (Snapchat page says base16, but in an example, it's in 64).
Check your urls, id, secret once again with those to get the authorization code.
:)

Ameritrade API POST Request JSON Response

I haven't coded in JAVA for years, and am trying to put an algorithm together to automatically make trades based on certain conditions.
I'm hoping to use the Ameritrade API
I've tried sending a cURL message in command prompt and I do indeed get a response back from the server 'Invalid Key'. I'd like to see the 'Invalid Key' response come back in Java as this will prove that I can send POST and receive JSON objects back into Java. From there I will work at authenticating but one step at a time!
Here's the curl message sent in command prompt that works, try it yourself by copying and pasting::
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=authorization_code&refresh_token=&access_type=offline&code=&client_id=&redirect_uri=" " https://api.tdameritrade.com/v1/oauth2/token
The first thing I'd like to do is be able to send this curl message in JAVA and receive the JSON response back in JAVA
This is what I have for code so far, but I get a 500 error, which makes me think its something with the way im sending the message to the server?
public void trytoAuthenticate() {
HttpURLConnection connection = null;
//
//this is the curl message in command prompt you can send to receive JSON response back
//curl -X POST --header "Content-Type: application/x-www-form-urlencoded" -d
//"grant_type=authorization_code&
//refresh_token=&
//access_type=offline&
//code=&
//client_id=&
//redirect_uri=" "https://api.tdameritrade.com/v1/oauth2/token"
try {
//Create connection
URL url = new URL("https://api.tdameritrade.com/v1/oauth2/token");
String urlParameters = "grant_type=" + URLEncoder.encode("authorization_code", "UTF-8") +
"&refresh_token=" + URLEncoder.encode("", "UTF-8") +
"&access_type=" + URLEncoder.encode("", "UTF-8") +
"&code=" + URLEncoder.encode("", "UTF-8") +
"&client_id=" + URLEncoder.encode("", "UTF-8") +
"&redirect_uri=" + URLEncoder.encode("", "UTF-8");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST"); //-X
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //-H
connection.setRequestProperty("Content-Length",
Integer.toString(urlParameters.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoOutput(true);//connection will be output
connection.setDoInput(true);//connection will be input
//Send request
DataOutputStream wr = new DataOutputStream (connection.getOutputStream());
wr.writeBytes(urlParameters);
System.out.println(urlParameters); //added for testing
wr.close();
//Get Response
DataInputStream is = new DataInputStream (connection.getInputStream());
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
rd.readLine();
//StringBuffer response = new StringBuffer(); // or StringBuffer/StringBuilder if Java version 5+
//String line;
//while ((line = rd.readLine()) != null) {
// response.append(line);
// response.append('\r');
//}
rd.close();
//System.out.println(response.toString());
//return response.toString();
} catch (Exception e) {
e.printStackTrace();
//return null;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}
A few things:
You need four parameters: grant_type, access_type, redirect_url and code.
You should URLDecode the authorization code you got from the browser login you probably just performed (as per their instructions)
Remove empty parameters, leave only what I mentioned above.
The redirect URL must match EXACTLY the redirect URL you added when you created your APP in the console.
If this is an app (looks like it), you probably have to set the access_type to "offline". Again see their documentation. Depends on your application.
grant_type should be "authorization_code", as that's what you want.

get MailChimp response with Java

I want to use the MailChimp api to add a subscriber. As a start, want to read from one of the REST I'm trying to get a response back from the MailChimp api.
I seem to be doing the authorization correctly as I'm getting status 200, but for some reason, I am not getting the response.
Here is the code so far:
public void doPostAction() throws IOException{
// BASIC Authentication
String name = "user";
String password = apikey;
String authString = name + ":" + password;
byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
String authStringEnc = new String(authEncBytes);
URL urlConnector = new URL(url);
HttpURLConnection httpConnection = (HttpURLConnection) urlConnector.openConnection();
httpConnection.setRequestMethod("GET");
httpConnection.setDoOutput(true);
httpConnection.setDoInput(true);
httpConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
httpConnection.setRequestProperty("Accept", "application/json");
httpConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
InputStream is = httpConnection.getInputStream();
// check status
System.out.println("DoPost: status: " + httpConnection.getResponseCode());
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
System.out.println("DoPost response: \n" + line);
br.close();
}
Looking at the MailChimp playground, it seems like I'm missing out on a lot...
How do I get the response?
****/ EDIT /****
If anyone's looking at the above code, the output should be:
System.out.println("DoPost response: \n" + sb); // not line
OK, the above code works. Basic error.
I was examining the line variable when it was null, not the response...
When I change to:
System.out.println("DoPost response: \n" + line); // not line
System.out.println("DoPost response: \n" + sb); // but sb StringBuilder
...it works.

Android app connecting to shutterstock api throws IOException with Error 401

I am trying to connect my android app to shutterstock api so that it can search for some images there. It uses https scheme + Basic Authentication header to allow users for all search requests. I implemented the functionality in a regular java project using HttpsURLConnection and was able to get correct JSON responses.
The java code looks like this:
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();//proxy);
String username = "62c01aa824222683004b", password = "dc4ad748a75e4e69ec853ad2435a62b700e66164";
String encoded = Base64.getEncoder().encodeToString((username+":"+password).getBytes("UTF-8"));
System.out.println(encoded.equals("Nj0jMDFhZWE4ZmE4MjY4MzAwNGI6ZGM0YWQ3NDhhNzVlNGU2gWVjODUzYWQ0ZmEzYTYyYjc7MGU2NjE2NA==")); // prints true
urlConnection.setRequestProperty("Authorization", "Basic "+encoded);
When ported this into Android, it was throwing an IOException with 401 error code. As explained in many posts on SO (like the one here), I modified the code accordingly with an extra try-catch as below:
String username = "62c01aa824222683004b", password = "dc4ad748a75e4e69ec853ad2435a62b700e66164", encoded = "";
encoded = Base64.encodeToString((username+":"+password).getBytes("UTF-8"), Base64.URL_SAFE);
Log.e("test", "encoded strings match:" + encoded.equals("Nj0jMDFhZWE4ZmE4MjY4MzAwNGI6ZGM0YWQ3NDhhNzVlNGU2gWVjODUzYWQ0ZmEzYTYyYjc7MGU2NjE2NA==") + "\n" + encoded); // prints false but string is same!!
URL url = new URL(reqUrl);
connection = (HttpsURLConnection) url.openConnection();
connection.setRequestProperty("Authorization", "Basic "+encoded);
try {
if (connection != null) {
connection.connect();
if (200 == connection.getResponseCode()) { // ---> throws IOException
BufferedReader br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
String output;
while ((output = br.readLine()) != null) {
Log.e("test", output);
response.append(output);
}
connection.disconnect();
return response.toString();
}
}
} catch (IOException e) {
try {
Log.e("test", e.getMessage()); // ---> prints "No authentication challenges found"
Log.e("test", connection.getResponseCode() + ":" + connection.getResponseMessage() + connection.getHeaderFields());
//---> prints 401:Unauthorized{null=[HTTP/1.1 401 Unauthorized], cache-control=[no-cache], Connection=[keep-alive], Content-Length=[38], Content-Type=[application/json; charset=utf8], Date=[Tue, 31 May 2016 14:11:28 GMT], Server=[nginx], X-Android-Received-Millis=[1464703888222], X-Android-Sent-Millis=[1464703887592], x-end-user-request-id=[f754ec7f-c344-431b-b641-360aabb70184], x-shutterstock-app-version=[apitwo-625], x-shutterstock-resource=[/v2/images/search]}
if (401 == connection.getResponseCode()) {
InputStream es = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(es));
String output;
while ((output = br.readLine()) != null) {
Log.e("test", output); // ---> prints {"message":"Invalid auth credentials"}
response.append(output);
}
connection.disconnect();
return response.toString();
} else {
Log.e("test","Could not connect! " + connection.getResponseCode() + ":" + connection.getResponseMessage() + ". " + connection.getRequestMethod());
}
}catch (Exception e1){e1.printStackTrace();}
}
I was unable to check the response headers in Firefox's Rest client because it does not send the request to server when I add the Authentication header.
So the questions here are:
Is this the right way to handle the 401 error in Android? Will I get the JSON response in the inner try-catch?
The java program uses exactly the same encoded string as in Android. How come the String.equals() returns "true" in java but "false" in android?
The error message from the server says "Invalid auth credentials". Does the encoded string differ between Android and Java for any reason? If yes, then point 2 makes sense.
I copied the encoded string from the java program into the Android variable and was able to authenticate successfully with shutterstock. So Indeed the encoded strings on Android and Java were different though in UTF-8 format. This also explains the "false" in Android and the "Invalid credentials" message from the server.
Just not sure why/how it differs when both the encoded strings are the same for the human eyes!

Categories