I’m trying to call an get api which is hosted in aws api gateway
via rest-assured
I’m able to sign the request and make a call. But to sign the request, I need to pass the full url to AWS to generate the Authorization Header.
For Ex. If I’m going to access an an endpoint
https://my-aws-api.com/basepath/v1/request/123
I need to sign the request via AWSSigner which needs the full endpoint to do so.
My current approach
String baseURI="https://my-aws-api.com"; String basePath="basepath/v1"; String requestPath="request/123"; String endpoint=baseURI+"/"+basePath+"/"+requestPath; Map<String,String> signedHeaders= aws4sign(endpoint,defaultHeaders); given() .log().ifValidationFails() .headers(signedHeaders) .when() .get(endpoint) .then() .log().ifValidationFails() .statusCode(200);
If I do that , then I cant use RestAssured’s baseURI
, basePath
and path params
I want to access it like
RestAssured.baseURI="https://my-aws-api.com"; RestAssured.basePath="basepath/v1"; given() .log().ifValidationFails() .pathParam("reqID", "123") .when() .get("request/{reqID}") .then() .log().ifValidationFails() .statusCode(200);
AwsSigner
public static Map<String, String> aws4Sign(String endpoint, Map<String, String> headers) throws URISyntaxException { String serviceName = "execute-api"; AWS4Signer aws4Signer = new AWS4Signer(); aws4Signer.setRegionName(EU_WEST_1.getName()); aws4Signer.setServiceName(serviceName); DefaultRequest defaultRequest = new DefaultRequest(serviceName); URI uri = new URI(endpoint); defaultRequest.setEndpoint(new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), "", "", "")); defaultRequest.setHttpMethod(HttpMethodName.GET); defaultRequest.setResourcePath(uri.getRawPath()); defaultRequest.setHeaders(headers); aws4Signer.sign(defaultRequest, DefaultAWSCredentialsProviderChain.getInstance().getCredentials()); return defaultRequest.getHeaders(); }
So My question is there any way, I can intercept the RestAssured’s request before it makes the call, so that I can get the fully generated end point and add the aws signed header to the call.
Advertisement
Answer
Thanks to @Ashaman.
The Filter Section is what I’m looking for
You can get the uri and other headers that were passed with requests from RequestSpec and then send it to the function to sign them and remove the old headers and put the new headers. Then forward the request
@BeforeAll public void init() { RestAssured.baseURI = "https://my-aws-api.com"; RestAssured.filters((requestSpec, responseSpec, ctx) -> { Map<String, String> headers = requestSpec.getHeaders() .asList() .stream() .collect(Collectors.toMap(Header::getName, Header::getValue)); Map<String, String> signedHeaders = aws4sign(requestSpec.getURI(), headers); requestSpec.removeHeaders(); requestSpec.headers(signedHeaders); return ctx.next(requestSpec, responseSpec); }); }
And for the tests I can use the features of Rest Assured normally
given() .log().ifValidationFails() .pathParam("reqID", "123") .when() .get("request/{reqID}") .then() .log().ifValidationFails() .statusCode(200);