Adding header for HttpURLConnection - java

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

Related

Sending a JSON formatted string through HttpUrlConnection

I've done some research on using HttpUrlConnect and most examples I've seen uses either
a) a params string which looks like this:
paramString = "param1=someParam&param2=2ndparam&param3=3rdparam";
b) uses a put method to place the parameters:
JSONObject json = new JSONObject();
json.put("param1", "Parameter");
json.put("param2", "Parameter2");
json.put("param3", "Parameter3");
The format I want to send looks like this:
{
"grant_type":"password",
"username":"testuser#someid.com",
"password":"testPwd123$"
}
Is there a way for me to send a formatted JSON string instead of setting parameters or using a param string? The code I'm using to send my POST request looks like the following:
public static String PostRequest(String urlString, String token, String jsonString) throws IOException {
byte[] postData = jsonString.getBytes(StandardCharsets.UTF_8);
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty ("Authorization", "Bearer " + token);
conn.setUseCaches(false);
try( DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
wr.write(postData);
}
int responseCode = conn.getResponseCode();
System.out.println("POST response code: " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
StringBuffer response = new StringBuffer();
while ((line = in.readLine()) != null) {
response.append(line);
}
in.close();
return response.toString();
}
I'm open to suggestions whether to use a different library, or if there are any code changes that I should make in order to take a JSON formatted string.

How to use cURL requests in 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?

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.

OpenId Connect to Google gives me Http 400

Im trying to access to Google APIs using OAuth 2.0
but i always receive the http 400 when i try to get the token
I'm using Tomcat8 with Java SDK 8
And i don't know what is wrong.
private void sendPost(
final String code,
final String clientId,
final String clientSecret,
final String redirectUri,
final String grantType) throws Exception {
String url = "https://accounts.google.com/o/oauth2/token";
StringBuffer strb = new StringBuffer();
strb.append("code=" + code);
strb.append("&client_id=" + clientId);
strb.append("&client_secret=" + clientSecret);
strb.append("&redirect_uri=" + redirectUri);
strb.append("&grant_type=" + grantType);
String urlParameters = strb.toString();
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
con.setRequestProperty("Content-Length", String.valueOf(urlParameters.length()));
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
System.out.println(response.toString());
}
My output is the following it seems that all parameters are ok.
Sending 'POST' request to URL : https://accounts.google.com/o/oauth2/token
Post parameters : code=<code>.InoAg9JcLi0boiIBeO6P2m94pmoskwI&client_id=<clientid>.apps.googleusercontent.com&client_secret=<secret>&redirect_uri=http://localhost:8080/Oauth/connect&grant_type=authorization_code
Response Code : 400
you'd want to url-encode the parameters
I don't think Google supports redirect_uri's pointing to "localhost" anymore so that would suggest that you got the "code" on a different redirect_uri than the one presented on the token endpoint request

Bearer Code returning HTTP 400 error for Twitter Search API V1.1

I am trying to implement the Twitter Search API V1.1
Please correct me if I am wrong.
I performed the below mentioned steps :
Step 1) Created an App in Twitter.
So I got the TWITTER_CONSUMER_KEY and TWITTER_CONSUMER_SECRETCODE.
Step 2) I encoded the concatenation of the above keys separated by ":" with the base UTF-8.
Step3 ) Get the bearer token with the above generated code.
Step4 ) Use the bearer code to get the Tweets on the relevance of a keyword.
I am stuck in Step 3,
where in I am getting the Response as::
Server returned HTTP response code: 400 for URL: https://api.twitter.com/oauth2/token
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
at com.tcs.crm.socialCRM.action.TwitterIntegration.requestBearerToken(TwitterIntegration.java:74)
at com.tcs.crm.socialCRM.action.TwitterIntegration.getStatusSearch(TwitterIntegration.java:27)
at com.tcs.crm.socialCRM.action.TwitterIntegration.main(TwitterIntegration.java:103)
My code is ::
HttpsURLConnection connection = null;
PrintWriter outWriter = null;
BufferedReader serverResponse = null;
try
{
URL url = new URL(endPointUrl);
connection = (HttpsURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Host", "api.twitter.com");
connection.setRequestProperty("User-Agent", "Search Tweets");
connection.setRequestProperty("Authorization", "Basic " + encodedCredentials);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
connection.setRequestProperty("Content-Length", "29");
connection.setUseCaches(false);
connection.setDoOutput( true );
logger.info("Point 1");
//CREATE A WRITER FOR OUTPUT
outWriter = new PrintWriter( connection.getOutputStream() );
logger.info("Point 2");
//SEND PARAMETERS
outWriter.println( "grant_type=client_credentials" );
outWriter.flush();
outWriter.close();
logger.info("Point 3");
//RESPONSE STREAM
serverResponse = new BufferedReader( new InputStreamReader( connection.getInputStream() ) );
JSONObject obj = (JSONObject)JSONValue.parse(serverResponse);
logger.info("The return string is "+obj.toString());
return obj.toString();
Please let me know how I can resolve this issue.
I had the same problem with the bearer token from Twitter. Also I test your same code and I received the error 403. After that I was creating my custom method to obtain the bearer token from twitter and I got the solution.
HttpClient httpclient = new DefaultHttpClient();
String consumer_key="YOUR_CONSUMER_KEY";
String consumer_secret="YOUR_CONSUMER_SECRET";
// Following the format of the RFC 1738
consumer_key=URLEncoder.encode(consumer_key, "UTF-8");
consumer_secret=URLEncoder.encode(consumer_secret,"UTF-8");
String authorization_header_string=consumer_key+":"+consumer_secret;
byte[] encoded = Base64.encodeBase64(authorization_header_string.getBytes());
String encodedString = new String(encoded); //converting byte to string
HttpPost httppost = new HttpPost("https://api.twitter.com/oauth2/token");
httppost.setHeader("Authorization","Basic " + encodedString);
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("grant_type", "client_credentials"));
httppost.setEntity(new UrlEncodedFormEntity(parameters));
httppost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httppost, responseHandler);
Good luck!
The Twitter dev doc tells to give the "Content-Length":
https://dev.twitter.com/oauth/application-only
(see at "Example Result" below "Step 2: Obtain a bearer token")
However, in my case (with PHP), it works only if I remove "Content-Length".
I know this is rather late, but i found that the following worked for me (thanks #jctd_BDyn for the code to encode the key and secret for basic auth):
private String createBasicAuth() throws UnsupportedEncodingException {
String consumer_key="YOUR_CONSUMER_KEY";
String consumer_secret="YOUR_CONSUMER_SECRET";
// Following the format of the RFC 1738
consumer_key=URLEncoder.encode(consumer_key, "UTF-8");
consumer_secret=URLEncoder.encode(consumer_secret,"UTF-8");
String authorization_header_string=consumer_key+":"+consumer_secret;
byte[] encoded = Base64.encodeBase64(authorization_header_string.getBytes());
return new String(encoded); //converting byte to string
}
private HttpURLConnection createBearerTokenConnection() throws IOException {
URL url = new URL("https://api.twitter.com/oauth2/token");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
connection.setRequestProperty("Authorization", "Basic " + createBasicAuth());
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
String formData = "grant_type=client_credentials";
byte[] formDataInBytes = formData.getBytes("UTF-8");
OutputStream os = connection.getOutputStream();
os.write(formDataInBytes);
os.close();
log.info("Sending 'POST' request to URL : " + bearerTokenUrl);
return connection;
}
public Optional<BearerToken> getBearerToken() {
try {
HttpURLConnection connection = createBearerTokenConnection();
int responseCode = connection.getResponseCode();
log.info("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
if (responseCode == 200) {
// Transforming from JSON string to POJO
return transformer.toBearerToken(response.toString());
} else {
log.error("Unexpected response code with response " + response.toString());
}
} catch (IOException e) {
log.error(String.format("IO exception on POST to %s", bearerTokenUrl), e);
}
return Optional.empty();
}

Categories