HTTP POST request with authorization on android - java

When I set "Authorization" header with setHeader from HttpPost then hostname disappears from request and there is always error 400 (bad request) returned. Same code is working fine on pure java (without android) and when I remove setting "Authorization" header also on android it works fine, but I need authorization.
This is a code (domain changed):
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://myhost.com/test.php");
post.setHeader("Accept", "application/json");
post.setHeader("User-Agent", "Apache-HttpClient/4.1 (java 1.5)");
post.setHeader("Host", "myhost.com");
post.setHeader("Authorization",getB64Auth());
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("data[body]", "test"));
AbstractHttpEntity ent=new UrlEncodedFormEntity(nvps, HTTP.UTF_8);
ent.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
ent.setContentEncoding("UTF-8");
post.setEntity(ent);
post.setURI(new URI("http://myhost.com/test.php"));
HttpResponse response =client.execute(post);
Method getB64Auth() returns "login:password" encoded using Base64 like: "YnxpcYRlc3RwMTulHGhlSGs=" but it's not important.
This is a piece of lighttpd's error.log when above code is invoked on pure java:
2011-02-23 15:37:36: (request.c.304) fd: 8 request-len: 308
POST /test.php HTTP/1.1
Accept: application/json
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: myhost.com
Authorization: Basic YnxpcYRlc3RwMTulHGhlSGs=
Content-Length: 21
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Encoding: UTF-8
Connection: Keep-Alive
HTTP/1.1 200 OK
Content-type: text/html
Transfer-Encoding: chunked
and record from access.log (IP changed):
1.1.1.1 myhost.com - [23/Feb/2011:15:37:36 +0100] "POST /test.php HTTP/1.1" 200 32 "-" "Apache-HttpClient/4.1 (java 1.5)"
When the same code is invoked on android, I get this in logs:
POST /test.php HTTP/1.1
Accept: application/json
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: myhost.com
Authorization: Basic YnxpcYRlc3RwMTulHGhlSGs=
Content-Length: 21
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Encoding: UTF-8
Connection: Keep-Alive
Expect: 100-Continue
2011-02-23 15:45:10: (response.c.128) Response-Header:
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 349
Connection: close
access.log:
1.1.1.1 - - [23/Feb/2011:15:45:10 +0100] "POST /test.php HTTP/1.1" 400 349 "-" "Apache-HttpClient/4.1 (java 1.5)"
How to get Authorization with POST working on android?
When I use HttpURLConnection instead of HttpClient it is no difference.

Thanks to Samuh for a hint :)
There was an extra newline character inserted which has no means in GET requests, but matters in POST ones.
This is proper way to generate Authorization header in android (in getB64Auth in this case):
private String getB64Auth (String login, String pass) {
String source=login+":"+pass;
String ret="Basic "+Base64.encodeToString(source.getBytes(),Base64.URL_SAFE|Base64.NO_WRAP);
return ret;
}
The Base64.NO_WRAP flag was lacking.

use simply this :
String authorizationString = "Basic " + Base64.encodeToString(
("your_login" + ":" + "your_password").getBytes(),
Base64.NO_WRAP); //Base64.NO_WRAP flag
post.setHeader("Authorization", authorizationString);

Related

How to GET/POST a ressource with OAuth 2.0 in JAVA (Status Code 415)

i have a implementation for oauth 2.0 in Java, i wanted to try out some things with the Shopware 6 API. I can get the access token without problems and, as far as i see, i'm doing everything right to request a ressource with this access_token. In the header for the GET Request i put the 'Authorization Bearer' + access_token header and also the "Content-Type", "application/json" header.
HttpGet get = new HttpGet(resourceURL);
get.addHeader("Content-Type", "application/json");
and later
if (isValid(accessToken)) {
// update the access token
// System.out.println("New access token: " + accessToken);
oauthDetails.setAccessToken(accessToken);
// remove the old auth header
get.removeHeaders(OAuthConstants.AUTHORIZATION);
// add the new auth header
get.addHeader(OAuthConstants.AUTHORIZATION,
getAuthorizationHeaderForAccessToken(oauthDetails.getAccessToken()));
get.releaseConnection();
response = client.execute(get);
code = response.getStatusLine().getStatusCode();
The Error Code i always get is 415.
This is the complete response:
HttpResponseProxy{HTTP/1.1 415 Unsupported Media Type [Date: Thu, 04 Jul 2019 08:45:38 GMT, Server: Apache/2.4.25 (Debian), Cache-Control: no-cache, private, Access-Control-Allow-Origin: *, Access-Control-Allow-Methods: GET,POST,PUT,PATCH,DELETE, Access-Control-Allow-Headers: Content-Type,Authorization,sw-context-token,sw-access-key,sw-language-id,sw-version-id, sw-version-id: , sw-language-id: , sw-context-token: , x-frame-options: deny, X-Debug-Token: c1766c, X-Debug-Token-Link: http://localhost:8000/_profiler/c1766c, X-Robots-Tag: noindex, Vary: Authorization, Keep-Alive: timeout=5, max=100, Connection: Keep-Alive, Transfer-Encoding: chunked, Content-Type: application/json] ResponseEntityProxy{[Content-Type: application/json,Chunked: true]}}
The endpoint im trying to get is the "http://localhost:8000/api/v1/category/" endpoint. If im doing this whole thing with Insomnia/Postman i get the expected category information.
Does anyone have any idea what could be wrong? What am i missing here?
Please add following header
'Accept': 'application/json'
As nuriselcuk pointed out in the comment, the missing thing was the Accept header.
I added
post.addHeader("Accept", "application/json");
and now its working fine.

Change header-body-separator with HttpURLConnection (from java.net)

I am sending a simple POST request with the built-in HttpURLConnection class, but I want to change the way Java separates the headers from the body (look at the outputs of tcpflow -a port 80 below). Here is the code:
// Create HttpURLConnection object
URL url = new URL("http://httpbin.org/post");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Set request method
connection.setRequestMethod("POST");
// Write body and "Content-Length" header
String body = "This+is+the+body+of+the+post+request.";
connection.setRequestProperty("Content-Length",
String.valueOf(body.length()));
connection.setDoOutput(true);
connection.getOutputStream().write(body.getBytes("US-ASCII"));
// Send request
int responseCode = connection.getResponseCode();
When I execute that code and look at what Java actually sends using tcpflow -a port 80 (prints all requests/responses on port 80), I see the following (I cut away the response):
192.168.178.113.54654-054.225.177.165.00080: POST /post HTTP/1.1
User-Agent: Java/9
Host: httpbin.org
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-type: application/x-www-form-urlencoded
Content-Length: 37
192.168.178.113.54654-054.225.177.165.00080: This is the body of the post request.
The headers are correct, the body is correct. But I can see that the body is transferred in a separate connection. I know that this is a problem with java.net.HttpURLConnection because when I try the same with Apache's HttpClient, tcpflow -a port 80 gives me:
192.168.178.113.39708-054.243.202.193.00080: POST /post HTTP/1.1
Content-Length: 37
Host: httpbin.org
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.3 (Java/9)
Accept-Encoding: gzip,deflate
This+is+the+body+of+the+post+request.
Here the body is sent with the headers, separated with just /r/n/r/n. I would like the Java library (java.net.HttpURLConnection) to do the same. Is that possible?
EDIT: I found out that the reason the server rejected my requests was not that the body was in a different packet (packet, not connection, as Julian Reschke pointed out) than the headers but just that I sent the wrong data facepalm.

Post with curl, postman works but java gives SSL error

I make a basic post request to get a token in Java and I always get SSL certificate Handshake error :
DefaultHttpClient httpclient = new DefaultHttpClient();
String encoding = "YXBwLmJidmEuS3JlZGlsdafasdfasdf0bzpUeHZUUDJLVEdiKkhmbGNJeHNUDQ1d2tEU1dGak9TUk1zSVN3d2owYzJlJE9adU5rVmVZ";
HttpPost httppost = new HttpPost("https://connect.bbva.com/token?grant_type=client_credentials");
httppost.setHeader("Authorization", "Basic " + encoding);
HttpResponse response = httpclient.execute(httppost);
I have tried doing the same with Advanced Rest Client and a shell command and it works like a charm:
curl -X POST -i -H "Content-Type: application/json" -H "Authorization: Basic YXBwLmJidmEuS3JlZGl0bzpUeHZUUDJLVEdiKkhmbGNJeHNUNHU2RDE3MkFFa2R2QDQ1d2tEU1dGak9TUk1zSVN3d2owYzJlJE9adU5rVmVZ" https://connect.bbva.com/token?grant_type=client_credentials
I have also checked curl with the correct truststore option, which my default java takes to check if there is no problem with truststore and there aint one:
-cacerts=/usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts
Now I have used in Java java.net.URLConnection library too to test but it does not work.
I have also tested it with the content type but to no avail:
("Content-Type", "application/json;charset=UTF-8");
I have also tested this on java7 and java8, oracle both.
I have tried everything, I as a basic, mediocre java developer could have.
Btw, incase it helps, my curl response comes with the following headers:
HTTP/1.1 200 OK
Date: Thu, 18 May 2017 09:29:11 GMT
Server: Apache-Coyote/1.1
X-Frame-Options: DENY
Strict-Transport-Security: max-age=63072000; includeSubdomains; preload
Cache-Control: no-cache
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json;charset=UTF-8
Expires: 0
Pragma: no-cache
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Length: 751
I also checked the ssl-debug-logs using:
System.setProperty("javax.net.debug", "all");
and it uses the correct truststore.
I fixed this error just by changing the Java version from java-oracle8 to java-openjdk8.

Jersey 2 gzip compression not have Content-Encoding header in response

I have read this: compress-responses-in-jersey and have Jersey 2 config:
#ApplicationPath("/jaxrs/")
public class AppConfig extends ResourceConfig {
public AppConfig() {
super(AdvertisementResource.class, MultiPartFeature.class);
packages("jaxrs");
EncodingFilter.enableFor(this, GZipEncoder.class, DeflateEncoder.class);
}
}
I have header Request:
GET http://localhost:8081/jaxrs/admin-adblock
Accept:application/json
Cache-Control:no-cache
Content-Type:application/json
Authorization:Basic c21h...
Accept-Encoding:gzip,deflate
But header response are:
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Accept-Encoding
Server: Jetty(9.2.2.v20140723)
Header in response Content-Encoding:gzip is missing only Vary: Accept-Encoding is appear if I have:
EncodingFilter.enableFor(this, GZipEncoder.class, DeflateEncoder.class);
If I remove compression and comment EncodingFilter row response header are:
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.2.2.v20140723)
or this:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 369
Server: Jetty(9.2.2.v20140723)
I`m testing with Intellij Rest Client Tool and I`m not sure if I receive compressed response from server?
I have download jersey sources and set breakpoint here and debug rest service web application with Intellij it appears that CONTENT_ENCODING gzip is added here:
response.getHeaders().putSingle(HttpHeaders.CONTENT_ENCODING, contentEncoding);
but its missing in response header from Intellij Rest Client tool..
I have download SoapUI and test the same Rest requests response headers:
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 204
Server: Jetty(9.2.2.v20140723)
The Intellij Rest Client Tool is hiding response headers Content-Encoding and Content-Length..
I have open new issue

Sending Headers with Axis (HTTP headers) - not SOAP headers

im using a generated axis client to consume a service that requires headers
when using SOAPUI, i add the headers and the request looks like this
POST https://fttoo/service/v3.2/SOAP HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
Authorization: Bearer 123
Content-Length: 270
Host: my host
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
when trying to set the headers with code i'm doing the following
proxy = (SessionServiceImplServiceSoapBindingStub)locator.getSessionService();
proxy._setProperty("Authorization", "Bearer 123");
this is not working well and i get Error 401, when inspecting the proxy object i see that a property called cachedProperties has the value of {Authorization=Bearer 123}
I've also tried proxy._setProperty(HTTPConstants.HEADER_AUTHORIZATION, "Bearer 123");
and also inside the stub, in the _call object....
given the fact that axis 1 is very old i generated a new web client using CXF instead of Axis, this way i was able to use cxf api to place the headers

Categories

Resources