I am trying to run my autotests with serenity and rest-assured, but the token is not included in my request generation method. The method of getting the token itself works correctly. tell me what could be the reason.
public class ApiSteps {
private String token;
public String getAccessToken() {
RequestSpecification requestSpec = RestAssured.with();
requestSpec.given().contentType("application/x-www-form-urlencoded");
Response giveToken = RestAssured.given()
.formParam("username", "user")
.formParam("password", "pass")
.request().post("https://test.com/token");
DocumentContext doc = JsonPath.parse(giveToken.asString());
token = doc.read("access_token");
System.out.println(token);
return token;
}
final RequestSpecification spec = new RequestSpecBuilder()
.setBaseUri("https://test.com/api/v1")
.addHeader("Content-Type","application/json")
.addHeader("Accept", "text/plain")
.addHeader("Authorization", "Bearer " + getAccessToken())
.build();
#Step
public void testRest() {
given()
.spec(spec)
.when()
.get("/Test")
.then()
.assertThat()
.statusCode(200);
}
}
when starting a test in a request - null. I tried to mark with the annotation #Before, but the result is the same
You need to move the method for getting the token into a separate class and use it as follows:
NameClass nameClass = new NameClass();
.addHeader("Authorization", "Bearer " + getAccessToken())
and here use the method of this class:
nameClass.getAccessToken()
Related
Have one token generation API in one class which gives the below response.
{
"access_token": "eyJraWQiOiJNR2FOQUtYXC9pa0grNE1wTE9aS05wMGtqbXNOd0lzXC9WXC9EYm1LZ0pZdTZNPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIxYjBtcjc4cHNjMHIyM25nYnJqMml1MnNkNCIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoic2dwZi5wcm9kdWN0XC",
"expires_in": 3600,
"token_type": "Bearer"
}
Then have another Get API in another class in which I want to extract this access_token value in the header in rest assured code. So how can I take that access token value in another class?
public class Get_Service_List {
private Response response;
String BaseUrl = "https://dev.api.sgf.eus.nt/pro";
#Given("Get Service list API")
public void get_Service_list_API() {
RestAssured.baseURI = BaseUrl;
}
#When("call the API with valid token and details")
public void call_the_API_with_valid_token_and_details() {
response = RestAssured.given()
.header("Content-Type", "application/json")
.header("Authorization", "Bearer "+TokenGeneration.accessToken)
.when()
.get("/api/protsvc/ser");
}
#Then("validate the resonse body with list of services")
public void validate_the_resonse_body_with_list_of_services() {
String response_body = response.getBody().asString();
System.out.println("response is: " +response_body);
}
#Then("validate for 200 status code")
public void validate_for_status_code() {
int status_code = response.getStatusCode();
System.out.println("status is: " +status_code);
}
}
I don't know much about how cucumber share state. Below is the way to extract access_token from response.
String accessToken = response.jsonPath().getString("access_token");
I am sending POST call to an endpoint with a controlname's contentbody that contain Vietnamese character (such as á ư, ồ, ự..).
Although request was sent successfully, those special characters were replaced by ??? like ch?a ???c n? where it should be chưa được nè at UI :
public class MakeCostObject {
RequestSpecBuilder requestSpec;
public MakeCostObject() {
requestSpec = new RequestSpecBuilder();
String note = "chưa được nè";
String status = "init";
requestSpec.addMultiPart("note", note);
requestSpec.addMultiPart("status", status);
}
public RequestSpecification createCost() {
public RequestSpecification createCost () {
return requestSpec.build();
}
}
}
This is POST request, spec is created from createCost function.
response = given()
.header("Content-type", "multipart/form-data")
.header("Authorization", token)
.when()
.spec(spec)
.post(APIPath.apiPath.POST_cost_upload);
response.then().assertThat().statusCode(201);
I tried another API (non form-data), and UI can display perfectly.
String str = "Tiếng việt";
Map<String, Object> body = new HashMap<>();
body.put("note", str);
given().spec(HeaderConfigs.headerwithnewToken())
.when()
.body(body)
.patch("/costdetail/xxxx/");
How can I config to encode or something to solve my issue?
My io.rest-assured version : 4.2.0.
Thanks.
I have solved the issue by myself. Just replace:
requestSpec.addMultiPart("note", note);
by
requestSpec.addMultiPart(new MultiPartSpecBuilder(note).controlName("note").charset(Charsets.UTF_8).build());
im new with rest assured and i make make one test to extract access token and some other params and i want to use these access token in the request headers for all other tests
is there away to set global header for all test methods i have, or make function to run once per all test and inject the required request header
#Test
public void getAccessToken (){
Response body =
given()
.params("username", "test#example.com","password","pass!","grant_type","password").post("https://example.test.com/Token")
.then()
.log().body()
.statusCode(200)
.extract().response();
String access_token = body.path("access_token").toString();
String token_type = body.path("token_type").toString();
String refresh_token = body.path("refresh_token").toString();
String Authorization = "bearer " + access_token; }
}
Update
i have added the following part below, but now getting 400 status code instead of 200 seems im missing something, down below i added to sample one of them works, and other one using RequestSpecification doesn't work
Worked as expected
public class PermissionTests {
Response body =
given()
.params("username", "user#example.com","password","pass!","grant_type","password").post("https://test.example.com/Token")
.then()
.log().body()
.statusCode(200)
.extract().response();
String access_token = body.path("access_token").toString();
String token_type = body.path("token_type").toString();
String refresh_token = body.path("refresh_token").toString();
String Authorization = "bearer " + access_token;
#Test
public void addNewGraph(){
given()
.header("officeId",1)
.header("organizationId",1)
.header("refreshToken",refresh_token)
.header("Authorization",Authorization)
.when()
.get("https://test.example.com/api/cases/recent")
.then()
.log().body()
.statusCode(200);
}
})
this sample doesnt work it returns 400 knowing that im using TestNG not JUnit
public class PermissionTests {
private static RequestSpecification requestSpec;
#BeforeClass
public static void AuthSetup() {
Response body =
given()
.params("username", "user#example.com","password","pass!","grant_type","password").post("https://test.example.com/Token")
.then()
.log().body()
.statusCode(200)
.extract().response();
String access_token = body.path("access_token").toString();
String token_type = body.path("token_type").toString();
String refresh_token = body.path("refresh_token").toString();
String Authorization = "bearer " + access_token;
HashMap<String, String> defaultHeader = new HashMap<>();
defaultHeader.put("officeId","1");
defaultHeader.put("organizationId","1");
defaultHeader.put("refresh_token",refresh_token);
defaultHeader.put("Authorization", Authorization);
RequestSpecBuilder builder = new RequestSpecBuilder();
builder.addHeader("officeId", "1");
builder.addHeader("organizationId", "1");
builder.addHeader("refresh_token", refresh_token);
builder.addHeader("Authorization", Authorization);
requestSpec = builder.build();
// specification = new RequestSpecBuilder()
//// .addHeaders(defaultHeader)
// .addHeader("officeId","1")
// .addHeader("organizationId","1")
// .addHeader("refresh_token",refresh_token)
// .addHeader("Authorization",Authorization)
// .build();
}
#Test
public void addNewGraph(){
given()
.spec(requestSpec)
.log().all()
.when()
.get("https://test.example.com/api/cases/recent")
.then()
.log().body()
.statusCode(200);
}
})
here is the log from last method
{
"access_token": "eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjE2MSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJha2FtZWxAdHJhY2tlcnByb2R1Y3RzLmNvbSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYWNjZXNzY29udHJvbHNlcnZpY2UvMjAxMC8wNy9jbGFpbXMvaWRlbnRpdHlwcm92aWRlciI6IkFTUC5ORVQgSWRlbnRpdHkiLCJBc3BOZXQuSWRlbnRpdHkuU2VjdXJpdHlTdGFtcCI6ImJmODQ1MTEwLTk0ZDEtNGE0Yi05YzkxLThlNWQ1NDI2YTYxMyIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2FkbWluIjoiVHJ1ZSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL3NpZCI6IjE2MSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VtYWlsYWRkcmVzcyI6ImFrYW1lbEB0cmFja2VycHJvZHVjdHMuY29tIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvb3JnYW5pemF0aW9uSWQiOiIxIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvb2ZmaWNlSWQiOiIxIiwicmVxdWlyZU1mYSI6IkZhbHNlIiwibmJmIjoxNTg4MTQ3MzMwLCJleHAiOjE1ODgxOTA1MzAsImlzcyI6Imh0dHBzOi8vdHJhY2tlcnByb2R1Y3RzLmNvbSIsImF1ZCI6ImM3MzJhY2U4MzRjZDQ4NTE5MGEzZTNhMjM2YTZhYzFkIn0.6pbDhYmyAXX9z46By4HxrCg_4HKRCSGq42FdhFoyA6s",
"token_type": "bearer",
"expires_in": 43199,
"refresh_token": "d64dde50sd4be16ef209dcc5ss",
"userName": "user#example.com",
"userId": "sds",
"deviceId": "eesdsde20d93e",
"maxStringFieldLength": "10000",
"opfs": "null",
".issued": "Wed, 29 Apr 2020 08:02:10 GMT",
".expires": "Wed, 29 Apr 2020 20:02:10 GMT"
}
Request method: GET
Request URI: https://example.test.com/api/cases/recent
Proxy: <none>
Request params: <none>
Query params: <none>
Form params: <none>
Path params: <none>
Headers: officeId=1
organizationId=1
refresh_token=d64dde50sd4be16ef209dcc5ss
Authorization=bearer eyA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjE2MSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzsdvY2xhaW1zL25hbWUiOiJha2FtZWxAdHJhY2tlcnByb2R1Y3RzLmNvbSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vYWNjZXNzY29udHJvbHNlcnZpY2UvMjAxMC8wNy9jbGFpbXMvaWRlbnRpdHlwcm92aWRlciI6IkFTUC5ORVQgSWRlbnRpdHkiLCJBc3BOZXQuSWRlbnRpdHkuU2VjdXJpdHlTdGFtcCI6ImJmODQ1MTEwLTk0ZDEtNGE0Yi05YzkxLThlNWQ1NDI2YTYxMyIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2FkbWluIjoiVHJ1ZSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL3NpZCI6IjE2MSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VtYWlsYWRkcmVzcyI6ImFrYW1lbEB0cmFja2VycHJvZHVjdHMuY29tIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvb3JnYW5pemF0aW9uSWQiOiIxIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvb2ZmaWNlSWQiOiIxIiwicmVxdWlyZU1mYSI6IkZhbHNlIiwibmJmIjoxNTg4MTQ3MzMwLCJleHAiOjE1ODgxOTA1MzAsImlzcyI6Imh0dHBzOi8vdHJhY2tlcnByb2RdZCI6ImM3MzJhY2U4MzRjZDQ4NTE5MGEzZTNhMjM2YTZhYzFkIn0.6pbDhYmyAXX9z46By4HxrCg_4HKRCSGq42FdhFoyA6s
accept=application/json, text/plain, */*
Cookies: <none>
Multiparts: <none>
Body: <none>
{
"message": "GENERAL.ERROR",
"errorId": "637237441331863542"
}
original request header from the browser
You can use the Specification Re Use of Rest Assured, Particularly the RequestSpecBuilder() since you need to re-use request data in different tests
public class PermissionTests {
private static RequestSpecification requestSpec;
#BeforeClass
public static void AuthSetup() {
Response body = given().log().all()
.params("username", "user#example.com", "password", "pass!", "grant_type", "password")
.post("https://test.example.com/Token").then().log().body().statusCode(200).extract().response();
String access_token = body.path("access_token").toString();
String token_type = body.path("token_type").toString();
String refresh_token = body.path("refresh_token").toString();
String Authorization = "bearer " + access_token;
RequestSpecBuilder builder = new RequestSpecBuilder();
builder.addHeader("officeId", "1");
builder.addHeader("organizationId", "1");
builder.addHeader("refresh_token", refresh_token);
builder.addHeader("Authorization", Authorization);
requestSpec = builder.build();
}
#Test
public void addNewGraph() {
given().spec(requestSpec).log().all().when().get("https://test.example.com/api/cases/recent").then().log()
.body().statusCode(200);
}
}
You could use RestAssured.requestSpecification to set a default request specification that will be sent with each request, e.g.
RestAssured.requestSpecification = new RequestSpecBuilder()
.build().header("Authorization", "Bearer " + token);
I am using Postman currently to generate Bearer Token, which I am using in my automated tests. Now I would like to automate also the Bearer Token generation process too using REST Assured in Java. Please help me. Thanks.
Response response =
given()
.auth()
.oauth(
"n0pCrq5SPgraZ3CyY0Nd",
"xvvx-LVd5dszLi9OO_1qjbU4eUQ4dXwLrDZN7oioSITr_EXrgsyyOvPvZmv85Ew2",
"",
"",
"HMAC-SHA256")
.when()
.get(url)
.then()
.contentType(ContentType.JSON)
.extract()
.response();
This is working. Thanks #wilfred clement.
public static String getOauthToken(String consumerKey, String consumerSecret, String endpoint ) {
log.info("GET ACCESS TOKEN=" + endpoint);
URI uri = null;
try {
uri = new URI(endpoint);
} catch (URISyntaxException e) {
log.error("Not proper oauth url=" + endpoint);
throw new RuntimeException(e);
}
ValidatableResponse res = given()
.header("Content-Type", "application/json")
.auth().oauth(consumerKey,
consumerSecret,
"",
"")
.body("{\"grantType\": \"client_credentials\"}").when().post(uri).then();
int responseCode = res.extract().statusCode();
if (HttpURLConnection.HTTP_OK == responseCode) {
String token = res.extract().jsonPath().get("accessToken").toString();
log.info("Auth token=" + token);
return token;
} else {
String msg = "Access token retrieve failed. Http response code=" + responseCode;
log.error(msg);
throw new RuntimeException(msg);
}
}
I'm building a rest API using Spring security Oauth2 to secure it.
The following curl command runs succesfully and I get the token:
curl -X POST -vu clientapp:123456 http://localhost:8080/dms-application-0.0.1-SNAPSHOT/oauth/token -H "Accept: application/json" -d "password=spring&username=roy&grant_type=password&scope=read%20write&client_secret=123456&client_id=clientapp"
The following test to get the token also runs succesfully:
#Test
public void getAccessToken() throws Exception {
String authorization = "Basic " + new String(Base64Utils.encode("clientapp:123456".getBytes()));
String contentType = MediaType.APPLICATION_JSON + ";charset=UTF-8";
// #formatter:off
String content = mvc
.perform(
post("/oauth/token")
.header("Authorization", authorization)
.contentType(
MediaType.APPLICATION_FORM_URLENCODED)
.param("username", "roy")
.param("password", "spring")
.param("grant_type", "password")
.param("scope", "read write")
.param("client_id", "clientapp")
.param("client_secret", "123456"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.access_token", is(notNullValue())))
.andExpect(jsonPath("$.token_type", is(equalTo("bearer"))))
.andExpect(jsonPath("$.refresh_token", is(notNullValue())))
.andExpect(jsonPath("$.expires_in", is(greaterThan(4000))))
.andExpect(jsonPath("$.scope", is(equalTo("read write"))))
.andReturn().getResponse().getContentAsString();
// #formatter:on
String token= content.substring(17, 53);
}
However, when calling the rest end point externally from a webapp using Spring RestTemplate gives me a http error 400.
Below the code:
#RequestMapping(value = "/authentication", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity authenticate(#RequestBody CredentialsDto credentials) {
try {
String email = credentials.getEmail();
String password = credentials.getPassword();
String tokenUrl = "http://" + env.getProperty("server.host") + ":8080" + "/dms-application-0.0.1-SNAPSHOT" + "/oauth/token";
// create request body
JSONObject request = new JSONObject();
request.put("username", "roy");
request.put("password", "spring");
request.put("grant_type","password");
request.put("scope","read write");
request.put("client_secret","123456");
request.put("client_id","clientapp");
// set headers
HttpHeaders headers = new HttpHeaders();
String authorization = "Basic " + new String(Base64Utils.encode("clientapp:123456".getBytes()));
String contentType = MediaType.APPLICATION_FORM_URLENCODED.toString();
headers.set("Authorization",authorization);
headers.set("Accept","application/json");
headers.set("Content-Type",contentType);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);
// send request and parse result
ResponseEntity<String> loginResponse = restClient.exchange(tokenUrl, HttpMethod.POST, entity, String.class);
// restClient.postForEntity(tokenUrl,entity,String.class,)
if (loginResponse.getStatusCode() == HttpStatus.OK) {
//JSONObject userJson = new JSONObject(loginResponse.getBody());
String response = loginResponse.getBody();
return ResponseEntity.ok(response);
} else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
// nono... bad credentials
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
}
return null;
}
And the error I get:
"Missing grant type"
Any ideas of what can be wrong or any other ways to do it? Because I'm completely stuck on this.
Thank you
Try to do it like this:
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("username", "roy");
map.add("password", "spring");
map.add("grant_type", "password");
map.add("scope", "read write");
map.add("client_secret","123456");
map.add("client_id","clientapp");
HttpEntity request = new HttpEntity(map, headers);
One more thing, when you ask for a token make sure not to send a json request, but with this header:
headers.add("Content-Type", "application/x-www-form-urlencoded");