Spring Boot REST API unrecognized token - java

I have a REST API and a WEB-app that makes request for that API. Both in Spring Boot.
I followed one of the many guides on this and testing the API in postman worked fine.
I also tested the API from my webapp and it also worked.
But when i run my API in docker with Traefik i get an error, but only from the webapp. Postman still works fine.
2020-10-27T13:31:10.334026053Z at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:na],
2020-10-27T13:32:34.827929610Z java.lang.RuntimeException: Could not read
requestcom.fasterxml.jackson.core.JsonParseException: Unrecognized token 'ssword': was expecting
(JSON String, Number, Array, Object or token 'null', 'true' or 'false')
In the request i post username and password as json in the body like this:
{
"username" : "user",
"password" : "dfgdhghdhdhfd"
}
This is the code that generates the request from the webapp:
JsonObject j = new JsonObject();
j.addProperty("username", API_USER);
j.addProperty("password", API_PASSWORD);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://myapi.local/login"))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(j.toString()))
.timeout(Duration.ofSeconds(2L))
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
return response.headers().firstValue("Authorization").get();
Is there any chance it gets truncated somehow as it refers to the latter half of the 'password' key? I'm unsure of even where to begin getting information to assist you in helping me.
To summarize:
Localhost webapp and postman to localhost API: Works
Localhost postman to Docker API: Works
Localhost webapp to Docker API: Does not work

Related

Can't use cookie in frontend but works fine in postman

I've created rest API in springboot that upon sending valid credentials returns jwt access token and saves refresh token in httpOnly cookie, when I send GET request to the API that uses cookie in postman it works just fine but when I try to fetch in react API returns error that indicates that there is no cookies
error_message: "Cannot read the array length because "array" is null"
So do I have to specify domain name If yes how do I do it while working on localhost (springboot is working on localhost:8080 and react localhost:3000).
How I currently create cookie:
public static Cookie createRefreshCookie(String refresh_token) {
Cookie jwtRefreshCookie = new Cookie("refresh_token", refresh_token);
jwtRefreshCookie.setMaxAge(2678400);
jwtRefreshCookie.setHttpOnly(true);
jwtRefreshCookie.setPath("/");
return jwtRefreshCookie;
}
Problem was caused by my fetch request in react that contained header withCredentials: true from library axios insead of fetch implementation of header credentials:"include".

Why 400 error code in POST call using Jersey client

I am calling a post request using Jersey rest client which contains no request body but contains authorization header. I am always getting 400 error. I tried from postman i got 200 response. Here is my code
ClientResponse response = null;
Client cliente=Client.create();
cliente.addFilter(new LoggingFilter(System.out));
WebResource webResource=cliente.resource("https://URL/token");
Builder builder = webResource.accept("application/json");
builder.type(MediaType.APPLICATION_JSON);
builder.header("Authorization", "Basic YbjjkwliOTQtNjRiYy00NWE5LWFhMzQtMTFhNDkyZZjNTVlOjZjYjk2OTMwNGE5YTQ3OTlhODVjZTM5MDFiMDEyMTI2";
builder.post(ClientResponse.class,Entity.json(""));
Don't use the way you are trying right now. Use HttpAuthenticationFeature from Jersey like this
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("username", "password");
 
final Client client = ClientBuilder.newClient();
client.register(feature);
If you are getting 200 success respone in postman and failure response in your application then you need to check your api with another api tester online tool. I had the same issue i put / at the last of end point.

Using Vert.x Web Client to send GET requests properly with headers

I have an internal endpoint that I am trying to send GET requests to with Vert.x Web Client with Java. So far, I am unable to successfully get any data back.
If I cURL the endpoint, it works just fine (these are internal endpoints). The service I am trying to send GET requests to requires a few headers , and data as well:
curl -H "Accept:application/json" -H "Content-Type:application/json" -H "alpha:192.168.10.20" -d '{"mutate":"*"}' http://my-endpoint.com/api/get-items
But if I try to use this in one of my router endpoints in Vert.x, I get an error:
WebClient webClient = WebClient.create(vertx);
webClient.get("http://my-endpoint.com/api/get-items")
.putHeader("Accept", "application/json")
.putHeader("Content-Type", "application/json")
.putHeader("alpha", "192.168.10.20")
.sendJsonObject(new JsonObject().put("mutate", "*"), ar -> {
if (ar.succeeded()) {
System.out.println("##### WEBCLIENT #####");
System.out.println(ar);
} else {
System.out.println("CAUSE: " + ar.cause().getMessage());
}
});
The error message I get from the else statement is:
CAUSE: Connection refused: localhost/127.0.0.1:80
What am I doing wrong? I've been using this for reference: Vert.x Web Client
===========================================
SOLUTION
===========================================
I had to change
webClient.get("http://my-endpoint.com/api/get-items")
to
webClient.post(80, "my-endpoint.com", "/api/get-items")
Also had to add .as(BodyCodec.jsonArray()) underneath the above line because the result I was getting was a Json Array.
You need to change
webClient.get("http://my-endpoint.com/api/get-items")
to
webClient.get(80, "my-endpoint.com", "/api/get-items")

Testing org.apache.http.entity.ContentType when the HTTP response content type doesn't contain a space

I am writing a test for an authorization server that tests that the content type of an oauth response is JSON. The authorization server is using spring-security-oauth2 2.0.1.4.RELEASE and my JUnit test is using rest-assured 2.9.0.
#Test
public void testTokenEndpoint() throws Exception {
// Client Credentials Grant
ResponseBody clientCredentialsGrantResponseBody =
given(this.spec)
.authentication().basic(VALID_CLIENT_ID, VALID_CLIENT_SECRET)
.queryParameter("grant_type", CLIENT_CREDENTIALS_GRANT)
.queryParameter("username", VALID_USERNAME)
.queryParameter("password", VALID_PASSWORD)
.queryParameter("scope", VALID_SCOPES)
.when()
.post(OAUTH_TOKEN_ENDPOINT)
.then()
.assertThat().contentType(is(ContentType.APPLICATION_JSON.toString()))
.extract().response().body();
}
When I run this test I am greeted with this failure
java.lang.AssertionError: 1 expectation failed.
Expected content-type is "application/json; charset=UTF-8" doesn't match actual content-type "application/json;charset=UTF-8".
So the value of the org.apache.http.entity.ContentType contains a space between the type and charset, but the the authorization server response content type does not.
Now I could get around this by doing
.assertThat().contentType(is(ContentType.APPLICATION_JSON.toString().replace(" ", "")))
But I feel that there must be a better way.
Is there a content type enum I can use that doesn't have a space? Can the authorization server be configured to include a space in the content type?
You could try using the following class from Spring: org.springframework.http.MediaType
It looks like there is no space in the implementation.

Not able to fetch header data in rest assured for rest web service of type GET

I have GET REST API, which sends some information in response header.
I am writing test case using rest assured framework, issue I am facing is, in response of GET API, I am not getting header string set by the server in rest API response.
I have checked the same API in Rest client and HTTP Resource, there I can see the header information set by server in API response.
But in rest assured Response object, header information set by server is not available.
Rest API code:
#Path("/download")
#GET
#Produces("application/zip")
public Response downloadContractZipFile(#PathParam("contractId") final String contractId) throws CMException{
ContractActionRequest contractActionRequest = new ContractActionRequest();
contractActionRequest.setId(contractId);
DownloadActionResponse downloadActionResponse = (DownloadActionResponse) executeAction(Action.DOWNLOAD, contractActionRequest);
Response res = Response
.ok(downloadActionResponse.getFilestream(), MediaType.APPLICATION_OCTET_STREAM)
.header("content-disposition",downloadActionResponse.getContentDisposition())
.header("Expires", "0")
.header("Content-Length", String.valueOf(downloadActionResponse.getContentLength()) )
.build();
return res;
}
Above you can see, API is returning Content-Length in header. But when I am invoking above API using rest assured framework, it does not receive "Content-Length" in header. Assert is getting failed.
Rest assured Test case code:
given().get(propertyURI).then().assertThat().header("Content-Length","7562");
java.lang.AssertionError: Expected header "Content-Length" was not "7562", was "null". Headers are:
X-Powered-By=Servlet/3.0
Cache-Control=no-cache, no-store
Cache-directive=no-cache
Pragma=no-cache
Pragma-Directive=no-cache
Expires=Thu, 01 Jan 1970 00:00:00 GMT
Content-Type=text/html;charset=UTF-8
x-authenticated=false
x-location=https://reena:9453/app/login.jsp?targetApp=OM
Content-Language=en-US
Transfer-Encoding=chunked
I suggest you try Karate instead of REST-Assured as it has much better support for validating response headers.
(disclaimer: am Karate dev)

Categories

Resources