I need to get some respones from some URL.
For this purpose I use http://unirest.io/java.html and Java.
Map<String, String> map = new HashMap<>();
map.put(key1, value1);
...
map.put(keyN, valueN);
String authToken = "{token}";
HttpResponse<String> response = Unirest.post(url)
.header("Authorization","Bearer " + authToken)
.header("Content-Type", "application/json")
.fields(map)
.asString();
As a result I receive response.getStatus() = 302 and some unexpected body.
At the same time I use Postman software to get the same responses. The settings are the following:
POST: url
Authorization: Type -> Bearer Token; Token = {{authToken}} // get the value from the previous request
Header :
"Authorization" : "Bearer " + {{authToken}}
Content-Type: application/json
Body:
{
key1 : value1,
...
keyN : valueN
}
And I get some expected response.
What makes the difference?
A 302 is a redirect response. Is it possible Postman is following the redirect and returning the resultant page? Take a look at the Location header in the response you get in Java, and see if following that gives you the same results you're seeing in Postman.
Related
I'm using rest assured to send a post with a generated body from a model class. The model class uses the builder pattern and I confirmed that it is getting built correctly:
Request body:
McpSalesInvoicesPost(invoices=[McpSalesInvoices(type=PRE_ORDER, amount=212.0, currencyCode=INR, transactionDate=2020-10-24T22:43:24, payments=[McpSalesPayments(type=CASH, amount=212.0, currencyCode=INR, reference=reference text sample 376, transactionDate=2014-08-20T19:23:51)])])
When I use that object in the rest assured post call I get an empty body in the request. Here is the rest assured code:
response = SerenityRest
.given()
.filters(Arrays.asList(new RequestLoggingFilter(), new ResponseLoggingFilter()))
.contentType(ContentType.JSON)
.header(new Header("x-openapi-clientid", "client-id-1"))
.body(requestBody)
.when()
.request(verb, SALES_BASE_URL + endpoint);
where request body is the built object mentioned above and this gives:
Body:
{
}
for the request. Any ideas on where I'm going wrong?
A
Maybe try .with().body(object).
response = SerenityRest
.given()
.filters(Arrays.asList(new RequestLoggingFilter(), new ResponseLoggingFilter()))
.contentType(ContentType.JSON)
.header(new Header("x-openapi-clientid", "client-id-1")).with().
.body(requestBody)
.when()
.request(verb, SALES_BASE_URL + endpoint);
I need to create tests using RestAssured - Java for testing REST API. In order to get an authentication token (OAuth 2.0), I need to send from postman request filled as in the screen below. However, in java tests, I can not use postman. Any idea how it should look like java code to get authentication token?
Below is an algorithm/snippet of how your code should look like:
Prerequisites:
Initial OAuth token and clientID should be taken and stored (in a DB or any data
storage).
Time of OAuth token generation must be stored
Refresh token must be stored.
Validity (For how long the current OAuth token is valid) of OAuth token must be known/stored.
Algorithm:
long validityOfOAuthToken = DB.get ("validityOfOAuthToken");
long OAuthGeneratedTimeInMillis = DB.get ("oAuthGeneratedTime");
long currentTimeInMillis = DateTime.now (DateTimeZone.UTC).getMillis ( );
if (currentTimeInMillis - OAuthGeneratedTimeInMillis > validityOfOAuthToken)
{
String clientID = DB.get ("clientID");
String refreshToken = DB.get ("refreshToken");
String accessToken = generateAccessToken (clientID, refreshToken); // API Invocation to get access token via refresh token
DB.save ("oauthToken", accessToken);
DB.save ("oAuthGeneratedTime", DateTime.now (DateTimeZone.UTC).getMillis ( ));
return accessToken;
}
else
{
return DB.get ("oauthToken");
}
Do note/store clientid and secret that you get from uaa server:
Then First try to call uaa for tokens :
Response response =
given()
.header("Authorization",<client id>:<client secret>)
.contentType("application/x-www-form-urlencoded")
.formParam("grant_type","authorization_code") .formParam("redirect_uri",REDIRECT_URL)
.formParam("response_type","code")
.formParam("code", AUTHORIZATION_CODE)
.formParam("client_id", CLIENT_ID)
.formParam("client_secret", CLIENT_SECRET)
.when()
.post(BASE_URI+"/oauth2/token");
Then Fetch out information of access token and token type like below:
JSONObject jsonObject = new JSONObject(response.getBody().asString());
String accessToken = jsonObject.get("access_token").toString();
String tokenType = jsonObject.get("token_type").toString();
log.info("Oauth Token with type " + tokenType + " " + accessToken);
Lastly call your endpoint by passing access token in header:
Response response =
given()
.headers(
"Authorization",
"Bearer " + accessToken,
"Content-Type",
ContentType.JSON,
"Accept",
ContentType.JSON)
.when()
.get(url)
.then()
.contentType(ContentType.JSON)
.extract()
.response();
Please try this .
Using "client_secret" and "client_id" it creates a bearerToken and later we can use it to authenticate.
RestAssured.baseURI = "http://coop.apps.symfonycasts.com/";
RestAssured.basePath = "/token";
// client_secret is different from oauth2 token
Response response = given()
.formParam("client_id","samapp")
.formParam("client_secret","f56f459193cee56817c2a99c205654b7")
.formParam("grant_type", "client_credentials").post("");
//To get token
String bearerToken = response.jsonPath().get("access_token");
System.out.println("The bearer token value is "+bearerToken);
Assert.assertEquals(200, response.getStatusCode(),"Status code mismatches");
This should work -
public class AuthenticationUtils {
public static String generateOAuth2Token() {
return "Bearer "+RestAssured.given().auth().basic("{YOUR_USERNAME}", "{YOUR_PASSWORD}")
.formParam("client_id", "{YOUR_CLIENT_ID}")
.formParam("client_secret", "{YOUR_SECRET}")
.formParam("grant_type", "client_credentials")
.formParam("{ANY_OTHER_TOKEN_NAME}", "{TOKEN_VALUE}")
.formParam("redirect_uri", "{http://take-me-here-next.com/api/endpoint}")
.when().post("https://{YOUR_TOKEN_URL}/oauth2/v2.0/token")
.then()
.extract().path("access_token");
}
}
substitute values within {} with your's
Grant type in question posted is Authrization code but everyone replied for client credential
I'm sending a request ro a service that set a cookie in the response :
HttpEntity<String> response = restTemplate.exchange
(myUrl,
HttpMethod.GET,
new HttpEntity<>(headers),
String.class);
I found that I can extract the cookie using this line of code :
String set_cookie = response.getHeaders().getFirst(HttpHeaders.SET_COOKIE);
However this returns: name_of_cookie=value_of_cookie
I know that I can make a String processing to extract the value of the cookie by name, but I want to find a better solution in the manner of :
response.getHeaders().getCookieValueByName(cookie_name)
The getCookieValueByName function do not exsist. Is there a function that does what I want to do ?
Sorry if the question is possibly repeated. I'm not familiar with Java and I'm stuck with a Cordova plugin which returns headers in a non-JSON structure which I think is Map.soString() presentation of request.headers()
//These parts works fine returning response body
HttpRequest request = HttpRequest.post(this.getUrlString());
this.setupSecurity(request);
request.headers(this.getHeaders());
request.acceptJson();
request.contentType(HttpRequest.CONTENT_TYPE_JSON);
request.send(getJsonObject().toString());
int code = request.code();
String body = request.body(CHARSET);
JSONObject response = new JSONObject();
response.put("status", code);
// in this line I must put JSON converted headers instead of request.headers()
response.put("headers", request.headers());
I've tried
String headers = request.headers().toString();
and
JSONObject headers = new JSONObject(request.headers());
to change the aforementioned line to
response.put("headers", headers);
but none of them worked.
How should I send headers as JSON in response?
More context:
Currently the response headers are:
{
null=[HTTP/1.0 200 OK],
Content-Type=[application/json],
Date=[Mon, 25 Jan 2016 07:47:31 GMT],
Server=[WSGIServer/0.1 Python/2.7.6],
Set-Cookie=[csrftoken=tehrIvP7gXzfY3F9CWrjbLXb2uGdwACn; expires=Mon, 23-Jan-2017 07:47:31 GMT; Max-Age=31449600; Path=/, sessionid=iuza9r2wm3zbn07aa2mltbv247ipwfbs; expires=Mon, 08-Feb-2016 07:47:31 GMT; httponly; Max-Age=1209600; Path=/],
Vary=[Accept, Cookie],
X-Android-Received-Millis=[1453708294595],
X-Android-Sent-Millis=[1453708294184], X-Frame-Options=[SAMEORIGIN]
}
and are sent in body of response. so I need to parse them, but I can't do.
This should be the way to do it:
JSONObject headers = new JSONObject(request.headers());
However, the "toString()" display of the headers seem to be showing a map entry with a null key. That won't work in JSON: an JSON object attribute name cannot be null. My guess is that the null key caused the crash.
So I think you need to filter out the "bad" entry; i.e. code it something like this:
JSONObject headers = new JSONObject()
for (Map.Entry entry: request.headers().entries()) {
if (entry.getKey() != null) {
headers.put(entry.getKey(), entry.getValue());
}
}
Using Jersey 2.19, How do I get a CSRF token from a server which uses Spring Security 3 and make a successful login? I have two projects, a client which uses REST, and a server which was created using JHipster.
First, I'm making a get request to http://localhost:8080 and I'm getting this response headers:
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Language:en
Content-Length:17229
Content-Type:text/html;charset=utf-8
Date:Tue, 21 Jul 2015 19:24:40 GMT
Expires:0
Last-Modified:Thu, 02 Jul 2015 17:07:31 GMT
Pragma:no-cache
Server:Apache-Coyote/1.1
Set-Cookie:CSRF-TOKEN=0902449b-bac7-43e8-bf24-9ec2c1faa48b; Path=/
X-Application-Context:application:dev:8081
X-Content-Type-Options:nosniff
X-XSS-Protection:1; mode=block
I extract the Set-Cookie header and I get the CSRF token from there. Then I'm making a post request this way:
http://localhost:8080/api/authentication?j_username=user&j_password=user&submit=Login
With this request headers:
Content-Type: application/x-www-form-urlencoded
X-CSRF-TOKEN: <extracted token>
Using Chrome's plugin postman, I can make a correct post request for login, but with Jersey, I'm unable to send correctly the CSRF token (I get 403 response).
This is the response:
{"timestamp":1437507680089,"status":403,"error":"Forbidden","message":"Expected CSRF token not found. Has your session expired?","path":"/api/authentication"}
This is the jersey code:
WebTarget hostTarget = getClient().target("http://localhost:8080");
Response r = hostTarget.request().get();
String header = r.getHeaderString("Set-Cookie");
String csrf = null;
List<HttpCookie> cookies = HttpCookie.parse(header);
for (HttpCookie c : cookies) {
if("CSRF-TOKEN".equals(c.getName())){
csrf = c.getValue();
break;
}
}
WebTarget loginTarget = hostTarget.path("/api/authentication");
loginTarget = loginTarget.queryParam("j_username", username)
.queryParam("j_password", password)
.queryParam("submit", "Login");
Builder req = loginTarget.request(MediaType.APPLICATION_JSON_TYPE);
if (csrf != null) {
req = req.header("X-CSRF-TOKEN", csrf);
}
Response cr = req.post(Entity.entity(null,
MediaType.APPLICATION_FORM_URLENCODED_TYPE));
System.out.println("Response: " + cr.readEntity(String.class));
Thanks for your time.
After much trial and error, I found the solution. Is important to take in count cookies (as indicated by Roman Vottner) for REST configuration to communicate with spring security. The important cookie that must be present is JSESSIONID and the header X-CSRF-TOKEN (or whatever header name is configured in the server), so capture them in a initial request and send them again.
I've decided to send all the cookies to the server in this way.
WebTarget hostTarget = getClient().target("http://localhost:8080");
Response r = hostTarget.request().get();
String headerCookies = r.getHeaderString("Set-Cookie");
Map<String, NewCookie> cookies = r.getCookies();
String csrf = cookies.get("CSRF-TOKEN").getValue();
WebTarget loginTarget = hostTarget.path("/api/authentication");
loginTarget = loginTarget.queryParam("j_username", username)
.queryParam("j_password", password)
.queryParam("submit", "Login");
Builder req = loginTarget.request(MediaType.APPLICATION_JSON_TYPE);
req = req.header("Cookie", headerCookies);
if (csrf != null) {
req = req.header("X-CSRF-TOKEN", csrf);
}
Response cr = req.post(Entity.entity(null,
MediaType.APPLICATION_FORM_URLENCODED_TYPE));
//The response is empty (in my case) with status code 200
System.out.println("Response: " + cr.readEntity(String.class));