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.
Related
I'm trying to update part of a legacy codebase I don't fully understand to work with a newer version of a REST API I also don't have access to the internals of. I do have a Swagger instance of it and can invoke it successfully via curl, but either Jersey is misbehaving or I'm misunderstanding how to read something.
If I execute the following curl command:
curl -v -k -X POST "[api endpoint]" -H "accept: application/json" -H "Authorization: Bearer [jwt token]" -H "Content-Type: multipart/form-data" -F "sender=[email address]" -F "recipient=[email address]" -F "fileType=file" -F "data=#[file]" -F "metaData=[other file]"
I get the following response:
> Content-Length: [#]
> Content-Type: multipart/form-data; boundary=------------------------9b1405ed70c2fd40
>
} [5 bytes data]
* We are completely uploaded and fine
{ [5 bytes data]
* Mark bundle as not supporting multiuse
< HTTP/1.1 201 Created
< Date: Wed, 26 Aug 2020 00:29:56 GMT
< Cache-Control: no-cache, no-store, must-revalidate
< Pragma: no-cache
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Set-Cookie: JSESSIONID=[ID];Path=/;Secure
< Keep-Alive: timeout=600
< X-Frame-Options: SAMEORIGIN
< Server: WildFly
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Connection: Keep-Alive
< Access-Control-Allow-Headers: Content-Type
< Content-Type: application/json
< Location: [value I care about]
< Content-Length: 0
<
100 1667 0 0 100 1667 0 1825 --:--:-- --:--:-- --:--:-- 1825
* Connection #0 to host [proxy] left intact
This implies to me that POST responses which have empty bodies but nonempty headers are valid. However, when I try to effect the same thing via Jersey:
ClientConfig config = new ClientConfig();
config.register(MultiPartFeature.class);
Client client = ClientBuilder.newClient(config);
WebTarget endpoint = client.target([uri]);
FormDataMultiPart post = new FormDataMultiPart()
.field("sender", [email], MediaType.TEXT_PLAIN_TYPE)
.field("recipient", [email], MediaType.TEXT_PLAIN_TYPE)
.field("fileType", "file", MediaType.TEXT_PLAIN_TYPE)
.field("data", [InputStream], MediaType.APPLICATION_OCTET_STREAM_TYPE)
.field("metaData", [other InputStream], MediaType.APPLICATION_OCTET_STREAM_TYPE);
JsonNode response = endpoint.path([api path])
.request(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + [jwtTokenString])
.post(Entity.entity(post, MediaType.MULTIPART_FORM_DATA_TYPE), JsonNode.class);
I get a null response even though I know from inspecting server logs that the API command was received and processed successfully.
After a long time with the debugger I've determined that this is because Jersey will either return a null object or throw an exception if the data is null. (See here for more context. Though oddly enough I can't find the section they reference in any of the specification documents I can turn up via Google.)
This is probably fine as I'm not really interested in the empty body of the response, but I can't figure out how to get the HTTP headers returned as a result of my POST in Java.
You can't get the headers because you are using the method to only ask for the body as the response. What you want is the entire Response object. To get that, leave out the last argument (JsonNode.class) to the .post() method. That overloaded method you're using says that you don't care about anything but the body of the response. And that's what you will get.
When you use the overloaded post() method without the last body type parameter, the return type will be Response. You can get headers from it and the body.
Response response = endpoint.path([api path])
.request(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + [jwtTokenString])
.post(Entity.entity(post, MediaType.MULTIPART_FORM_DATA_TYPE));
URI locationUri = response.getLocation();
String locationHeader = response.getHeaderString("Location");
String body = response.readEntity(String.class);
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.
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
I am able to set content type using cxf library but I don't know how to set Authorization header. Whenever I set user name and password then it set Authorization header and encode whole value and add Basic. I don't want to do this. I want to add Authorization header with plain string which ever I provide. Please help me to solve out this problem.
AMPServices services = new AMPServices();
CoreXmlPort coreXmlPort = services.getAMPSoapService();
Client client = ClientProxy.getClient(coreXmlPort);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy=httpConduit.getClient();
String contentType=httpClientPolicy.getContentType();
contentType="application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8";
httpClientPolicy.setContentType(contentType);
AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
authorizationPolicy.setUserName("username");
authorizationPolicy.setPassword("password");
httpConduit.setAuthorization(authorizationPolicy);
It generates following request xml.
POST https://api.iship.com/Root/Enterprises/Pitney%20Bowes/Progistics; HTTP/1.1
Content-Type: application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8
Accept: */*
Authorization: Basic aXNoaXAgcGIvd3NkZXZlbDowNzZhNjFjYTM5MDcxODAxODVjNWRkMjM2YTdkMzZhNGQ1ODg5OWFj
User-Agent: Apache CXF 3.1.0
Cache-Control: no-cache
Pragma: no-cache
Host: api.iship.com
Connection: keep-alive
Content-Length: 246
But I want this type of request
POST https://api.iship.com/Root/Enterprises/Pitney%20Bowes/Progistics; HTTP/1.1
Content-Type: application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8
Accept: */*
Authorization: username;password
User-Agent: Apache CXF 3.1.0
Cache-Control: no-cache
Pragma: no-cache
Host: api.iship.com
Connection: keep-alive
Content-Length: 246
But I was not able to do it. Please help me to solve out this problem.
Thanks,
Awadhendra
I think you are trying to call is a RestFul Service, so that's why the server side always response with a different content type than you expected (json instead of soap/xml). Is your url endpoint based on http protocol? If yes, do you need send additional parameters to this url?
The issue here is that the client you are using to interact with Webservice expecting XML based Soap Messages , while the service is serving JSON as a return media.
Either convert your client to use the JSON format and communicate using that, or alternatively use the XML based endpoint , consult with webservice provider for that.
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);