How to use cURL requests in Java - java

I am trying to get some authorisation codes from Spotify. I use the athorisation flow described here: https://developer.spotify.com/web-api/authorization-guide/#authorization-code-flow. Now I am stuck at number four: "Your application requests refresh and access tokens" I have to ask Spotify for accses_token and refresh_token with an cURL request. The cURL request has to be something like this:
curl -H "Authorization: Basic ZjM...zE=" -d grant_type=authorization_code -d code=MQCbtKe...44KN -d redirect_uri=http://localhost/codeAuslesen.php https://accounts.spotify.com/api/token
I tryed to achieve this with :
String clientId = <client_Id>;
String clientSecret = <clientSecret>;
String getTokenUrl = "https://accounts.spotify.com/api/token";
String encodeString = clientId + ":" + clientSecret;
String basicAuth = "Basic " + Base64.getEncoder().encode(encodeString.getBytes());
String url = getTokenUrl;
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", basicAuth);
conn.setRequestProperty("grant_type", "authorization_code");
conn.setRequestProperty("code", code);
conn.setRequestProperty("redirect_uri", redirectUri);
try {
BufferedReader tokenReader = new BufferedReader(new InputStreamReader(conn.getInputStream())); //Exception points here
while((tokenLine = tokenReader.readLine()) != null) {
tokenResult += tokenLine;
}
tokenReader.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(tokenResult);
}
I am just getting this Exception:
java.io.IOException: Server returned HTTP response code: 400 for URL: https://accounts.spotify.com/api/token
Does someone see what I am doing wrong?

Related

set the (OAuth token) Authorization Header on SpringBoot

I have to send a Get Request to Request the Token URL with these Headers:
Content-Type: application/x-www-form-urlencoded
Authorization:
OAuth oauth_consumer_key="your_consumer_key",
oauth_nonce="random_string_or_timestamp",
oauth_signature="your_consumer_secret&",
oauth_signature_method="PLAINTEXT",
oauth_timestamp="current_timestamp",
oauth_callback="your_callback"
User-Agent: some_user_agent
I've tried with this piece of code:
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization: OAuth oauth_consumer_key", "BaeUqWMTmCxjeJj9mkJr");
conn.setRequestProperty("Authorization: oauth_nonce", "random_string_or_timestamp");
conn.setRequestProperty("Authorization: oauth_signature", "ZWglyBtJasnJBqVndzyduYJggCduKeYks&");
conn.setRequestProperty("Authorization: oauth_timestamp", String.valueOf(new Date()));
conn.setRequestProperty("Authorization: oauth_callback", "http://localhost:8080");
conn.setRequestProperty("User-Agent", "test");
int statusCode = conn.getResponseCode();
System.out.println("Response from WA Gateway: \n");
System.out.println("Status Code: " + statusCode);
BufferedReader br = new BufferedReader(new InputStreamReader(
(statusCode == 200) ? conn.getInputStream() : conn.getErrorStream()
));
String output;
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
But I get this error:
Illegal character(s) in message header field: Authorization: OAuth oauth_consumer_key
The problem is that you're not forming your request correctly. Since it's a GET version of OAuth request, here's an example from RFC5849 on how to do this
GET /example/path?oauth_consumer_key=0685bd9184jfhq22&
oauth_token=ad180jjd733klru7&oauth_signature_method=HM
AC-SHA1&oauth_signature=wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%
3D&oauth_timestamp=137131200&oauth_nonce=4572616e48616
d6d65724c61686176&oauth_version=1.0 HTTP/1.1
Sp, set an Authorization header in the setRequestProperty following the format above:
...
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
String yourUrl = "http://yourwebsite.com";
String currentSeconds = 1618496867; // current seconds
String authorizationValue = "OAuth oauth_consumer_key=\"BaeUqWMTmCxjeJj9mkJr\",
oauth_nonce=\"1618496867\",
oauth_signature=\"ZWglyBtJasnJBqVndzyduYJggCduKeYks&\",
oauth_signature_method=\"PLAINTEXT\",
oauth_timestamp=\"1618496867\",
oauth_callback=\"http://localhost:8080\""
conn.setRequestProperty("Authorization", authorizationValue);
conn.setDoOutput(true);
conn.setRequestMethod("GET");
...
I tested a similar request using a Postman client for my OAuth authentication server and it worked perfectly.
These are not headers, you have to compute it.. Like this
https://twittercommunity.com/t/solved-java-oauth-request-token-flow-example-without-libraries/1440

Java equivalent HTTP post method for given curl code

What is the Java Equivalent Post method code for the curl?
curl -X POST https://api.twilio.com/2010-04-
01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Messages.json \
--data-urlencode "From=+15017122661" \
--data-urlencode "Body=body" \
--data-urlencode "To=+15558675310" \
-u ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:your_auth_token
This is my code:
String message = "Body=" + "This is your message";
String sender = "&From=" + "+14708657743";
String numbers = "&To=" + "+919943666843";
String auth = "ACb3739c0a4bf6d2cc5495a8ff3c545ea9:9ae02782844f6349d24a36bf922746b2";
auth = Base64.getEncoder().encodeToString(auth.getBytes());
String data = message + sender + numbers+ auth;
URL url = new URL("https://api.twilio.com/2010-04-01/Accounts/ACb3739c0a4bf6d2cc5495a8ff3c545ea9/Messages.json?"+URLEncoder.encode(data,"UTF-8"));
System.out.println(url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Basic " + auth);
Where did I go wrong? Can anyone suggest the correct code?

Java alternative for curl -T

i must send one text string using java to a IP web cam, before it take picture. So after I read the camera user manual and searched in google, the only thing i found was using cURL. I install it and its run fine, and everything is okay, the text from the file appear in the video streaming. The command is this
curl -T test.xml http://admin:pass#192.168.0.1/Video/inputs/channels/2/overlays/text/2
and the content of test.xml is:
<TextOverlay xmlns="http://www.hikvision.com/ver10/XMLSchema" version="1.0">
<id>2</id>
<enabled>true</enabled>
<posX>5</posX>
<posY>5</posY>
<message>Text here </message>
</TextOverlay>
So I want to send this content using Java, I already tried using post and java.net but I get an error "Server returned HTTP response code: 403 for URL"
Here is my code:
System.out.println("Starting......");
URL url = new URL("http://192.168.0.1/Video/inputs/channels/2/overlays/text/2/");
String data = "<TextOverlay xmlns=\"http://www.hikvision.com/ver10/XMLSchema\" version=\"1.0\">\n"
+ "<id>2</id>\n"
+ "<enabled>true</enabled>\n"
+ "<posX>5</posX>\n"
+ "<posY>5</posY>\n"
+ "<message>Text here</message>\n"
+ "</TextOverlay>";
HttpURLConnection httpConnection = prepareConn(url, null, "admin", "pass");
httpConnection.setDoOutput(true);
httpConnection.setDoInput(true);
httpConnection.setRequestMethod("POST");
httpConnection.setRequestProperty ( "Content-Type", "text/xml" );
OutputStreamWriter out = new OutputStreamWriter(httpConnection.getOutputStream());
out.write(data);
out.flush();
out.close();
System.out.println("Printing......");
System.out.println(httpConnection.getResponseCode());
System.out.println(httpConnection.getResponseMessage());
InputStreamReader reader = new InputStreamReader(httpConnection.getInputStream());
StringBuilder buf = new StringBuilder();
char[] cbuf = new char[2048];
int num;
while(-1 != (num = reader.read(cbuf)))
{
buf.append(cbuf, 0, num);
}
String result = buf.toString();
System.out.println("\nResponse received from server after POST" + result);
}
static private HttpURLConnection prepareConn(final URL url, Properties request_props, String username, String password) throws Error, IOException
{
System.out.println("Authorization......");
if (!url.getProtocol().equalsIgnoreCase("http"))
throw new Error(url.toString() + " is not HTTP!");
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(300);
conn.setRequestMethod("POST");
final Properties DEFAULT_REQUEST_PROPS = new Properties();
DEFAULT_REQUEST_PROPS.setProperty("charset", "utf-8");
final Properties props = new Properties(DEFAULT_REQUEST_PROPS);
if (request_props != null)
for (final String name : request_props.stringPropertyNames())
props.setProperty(name, request_props.getProperty(name));
for (final String name : props.stringPropertyNames())
conn.setRequestProperty(name, props.getProperty(name));
if(null != username && null != password)
conn.setRequestProperty("Authorization", "Basic " + new BASE64Encoder().encode((username+":"+password).getBytes()));
return conn;
}
Hope someone can help :)
All the best !
I just use wrong RequestMethod, after deep research I found that i must use PUT not POST request. Now just change setRequestMethod("POST") to setRequestMethod("PUT") and works like a charm.

Difference between Java Post Request and browser post request

I am trying to use api of one popular russian social networks. I am using OAuth via Java HttpUrlConnection. The problem is, when I send post data via Java, I get 401 response code. When I copy request and paste it browser, I get redirect to URL containing access token I need. That means that my post request is correct, but why when I send it with Java I get 401 error? When I send request with incorrect password, I get 200. It means that request is correct too.
private void getHomeAuth() throws Exception {
String url = "https://oauth.vk.com/authorize?client_id=APP_ID&scope=friends&redirect_uri=https://oauth.vk.com/blank.html&display=page&v=5.34&response_type=token";
URL oauth = new URL(url);
HttpURLConnection connection = (HttpURLConnection) oauth.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = connection.getResponseCode();
System.out.println("Response code: " + responseCode);
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while((inputLine = reader.readLine()) != null)
response.append(inputLine + "\n");
reader.close();
PrintWriter writer = new PrintWriter("auth.html");
writer.print(response);
writer.close();
parse();
cookies = connection.getHeaderField("Set-Cookie");
referer = connection.getURL().toString();
}
private void postAuth() throws Exception {
email = URLEncoder.encode("example#gmail.com", "UTF-8");
password = "password";
_origin = URLEncoder.encode(_origin, "UTF-8");
String url = "https://login.vk.com/?act=login&soft=1";
URL post = new URL(url);
String urlParameters = "ip_h=" + ip_h + "&_origin=" + _origin + "&to=" + to + "&expire=" + expire + "&email=" + email + "&pass=" + password;
HttpsURLConnection con = (HttpsURLConnection) post.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Cookie", cookies);
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("Sent post. Response code: " + responseCode + "\nRequest: " + post.toString() + urlParameters + "\nRequestMethod: " + con.getRequestMethod());
}
I also tryied to send this request via addon in browser, and the result was correct. I obtained access token from redirect link.
Maybe the problem is that something inside request is incorrect. I have tried to monitor requests from java app, but I failed.
My experience with this kind of problem is that the http request that first authenticates the user also puts cookies (scope varies from case to case) into the response and subsequent http requests are expected to contain those cookies. Look very closely at the complete returned response headers to see what cookies might have been returned.

Adding header for HttpURLConnection

I'm trying to add header for my request using HttpUrlConnection but the method setRequestProperty() doesn't seem working. The server side doesn't receive any request with my header.
HttpURLConnection hc;
try {
String authorization = "";
URL address = new URL(url);
hc = (HttpURLConnection) address.openConnection();
hc.setDoOutput(true);
hc.setDoInput(true);
hc.setUseCaches(false);
if (username != null && password != null) {
authorization = username + ":" + password;
}
if (authorization != null) {
byte[] encodedBytes;
encodedBytes = Base64.encode(authorization.getBytes(), 0);
authorization = "Basic " + encodedBytes;
hc.setRequestProperty("Authorization", authorization);
}
I have used the following code in the past and it had worked with basic authentication enabled in TomCat:
URL myURL = new URL(serviceURL);
HttpURLConnection myURLConnection = (HttpURLConnection)myURL.openConnection();
String userCredentials = "username:password";
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));
myURLConnection.setRequestProperty ("Authorization", basicAuth);
myURLConnection.setRequestMethod("POST");
myURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
myURLConnection.setRequestProperty("Content-Length", "" + postData.getBytes().length);
myURLConnection.setRequestProperty("Content-Language", "en-US");
myURLConnection.setUseCaches(false);
myURLConnection.setDoInput(true);
myURLConnection.setDoOutput(true);
You can try the above code. The code above is for POST, and you can modify it for GET
Just cause I don't see this bit of information in the answers above, the reason the code snippet originally posted doesn't work correctly is because the encodedBytes variable is a byte[] and not a String value. If you pass the byte[] to a new String() as below, the code snippet works perfectly.
encodedBytes = Base64.encode(authorization.getBytes(), 0);
authorization = "Basic " + new String(encodedBytes);
If you are using Java 8, use the code below.
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
String basicAuth = Base64.getEncoder().encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8));
httpConn.setRequestProperty ("Authorization", "Basic "+basicAuth);
Finally this worked for me
private String buildBasicAuthorizationString(String username, String password) {
String credentials = username + ":" + password;
return "Basic " + new String(Base64.encode(credentials.getBytes(), Base64.NO_WRAP));
}
Your code is fine.You can also use the same thing in this way.
public static String getResponseFromJsonURL(String url) {
String jsonResponse = null;
if (CommonUtility.isNotEmpty(url)) {
try {
/************** For getting response from HTTP URL start ***************/
URL object = new URL(url);
HttpURLConnection connection = (HttpURLConnection) object
.openConnection();
// int timeOut = connection.getReadTimeout();
connection.setReadTimeout(60 * 1000);
connection.setConnectTimeout(60 * 1000);
String authorization="xyz:xyz$123";
String encodedAuth="Basic "+Base64.encode(authorization.getBytes());
connection.setRequestProperty("Authorization", encodedAuth);
int responseCode = connection.getResponseCode();
//String responseMsg = connection.getResponseMessage();
if (responseCode == 200) {
InputStream inputStr = connection.getInputStream();
String encoding = connection.getContentEncoding() == null ? "UTF-8"
: connection.getContentEncoding();
jsonResponse = IOUtils.toString(inputStr, encoding);
/************** For getting response from HTTP URL end ***************/
}
} catch (Exception e) {
e.printStackTrace();
}
}
return jsonResponse;
}
Its Return response code 200 if authorizationis success
With RestAssurd you can also do the following:
String path = baseApiUrl; //This is the base url of the API tested
URL url = new URL(path);
given(). //Rest Assured syntax
contentType("application/json"). //API content type
given().header("headerName", "headerValue"). //Some API contains headers to run with the API
when().
get(url).
then().
statusCode(200); //Assert that the response is 200 - OK
It work for me.
I had to send request to another hand, and transfer header "Authorization" + jwt and some params via POST. By another side we formed jettyRequest with params and headers. If I send this sequence of code:
URL url = new URL(serviceURL);
HttpURLConnection myURLConnection = (HttpURLConnection)url.openConnection();
myURLConnection.setRequestMethod("POST");
myURLConnection.setRequestProperty ("Authorization", jwt); // <---- this place
// some code add params
then I received only params in a body.
If I send this:
URL url = new URL(serviceURL);
HttpURLConnection myURLConnection = (HttpURLConnection)url.openConnection();
myURLConnection.setRequestProperty ("Authorization", jwt); // <---- this place
myURLConnection.setRequestMethod("POST");
// some code add params
then I received headers Authorization and params.
Step 1: Get HttpURLConnection object
URL url = new URL(urlToConnect);
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
Step 2: Add headers to the HttpURLConnection using setRequestProperty method.
Map<String, String> headers = new HashMap<>();
headers.put("X-CSRF-Token", "fetch");
headers.put("content-type", "application/json");
for (String headerKey : headers.keySet()) {
httpUrlConnection.setRequestProperty(headerKey, headers.get(headerKey));
}
Reference link

Categories