I get HTTP/1.1 401 Unauthorized for subsequent API calls using RestAssured.
First call is for login and then license aggrement acceptance. For the same two APIs of another service need to be called. After first API call success response, the second API call, most of the times give 401 error but some times it gives 204.
These API call works fine with postman collection.
#RestController
#RequestMapping(value = "/url")
public class AController {
#ApiOperation(value = "testMethod")
#GetMapping(value = "testMethod", consumes = "application/json", produces = "application/json")
public ResponseEntity<String> testMethod()
throws Throwable {
//login
System.out.println(" Login ................ ");
Map<String, String> loginRequest = new LinkedHashMap<>();
loginRequest.put("username", "loginname");
loginRequest.put("password", "pass");
loginRequest.put("domain", "pass");
Response loginResponse = RestAssured.given().relaxedHTTPSValidation().contentType("application/json")
.cookie("JSESSIONID", "dummy")
.body(loginRequest).log().all().when().post("https://ip:port/url")
.then().log().all().extract().response();
Cookies coockies =loginResponse.getDetailedCookies();
//acceptance
System.out.println("acceptance....................");
Map<String, String> agreeRequest = new LinkedHashMap<>();
agreeRequest.put("aggrementAccepted", "Y");
Response agreeResponse = RestAssured.given().relaxedHTTPSValidation().contentType("application/json")
.cookies(cookies)
.header("A_COOK2",coockies.getValue("A_COOK2"))
.log().all()
.body(agreeRequest).when().post("https://ip:port/url")
.then().log().all().extract().response();
return new ResponseEntity<String>(agreeResponse, HttpStatus.OK);
}
}
######Log of Request and Response #######
----Error Response for acceptance:
Request method: POST
Request URI: https://ip:port/url
Proxy: <none>
Request params: <none>
Query params: <none>
Form params: <none>
Path params: <none>
Headers: Accept=*/*
Content-Type=application/json; charset=UTF-8
Cookies: <none>
Multiparts: <none>
Body:
{
"username": "loginname",
"password": "pass",
"domain": "pass"
}
HTTP/1.1 200 OK
Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-
eval'; style-src 'self' 'unsafe-inline'
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=15768000
X-Download-Options: noopen
X-XSS-Protection: 1; mode=block
X-FRAME-OPTIONS: SAMEORIGIN
transfer-encoding: chunked
Content-Type: application/json; charset=utf-8
setcookie: A_COOK2= p29YwlWxWXhZGO1ZgLew2/z4jWZxo3hMnkepe
JOEENILyRNbKv1pOSOY7Zr25g8jAHqtyhUjFkw3i7jD5Y9IcYu+OuA=; Path=/;
Secure
set-cookie: A_COOK1 =bqvRVooK7RXQMBC98EYrX1uS8IyPlaT4
dSHyjXC81lJFoZdU0ihYiDtZ893fL6hm5r2V7c+CgfY1Ds2f6RF
VGaGYe7VT4h4m27ATrl7lRZOecFprdTWdpOQ+UG2htcauUAVuW
Heqr1NL4glhrloEYQ==; Path=/; Secure;
HTTPOnly
{
"userName": "loginname",
"role": "Admins",
"appMode": "APPL",
"isRegistrationDone": false,
"exp": "2022-04-01T01:35:07.000Z",
"currentSystemTime": "2022-04-01T01:05:07.082Z"
}
acceptance....................
Request method: POST
Request URI: https://ip:port/url
Proxy: <none>
Request params: <none>
Query params: <none>
Form params: <none>
Path params: <none>
Headers: A_COOK2=p29YwlWxWXhZGO1ZgLew2/z4jWZxo3hMnkepe
JOEENILyRNbKv1pOSOY7Zr25g8jAHqtyhUjFkw3i7jD5Y9IcYu+OuA=
Accept=*/*
Content-Type=application/json; charset=UTF-8
Cookies: A_COOK2=p29YwlWxWXhZGO1ZgLew2/z4jWZxo3
hMnkepeJOEENILyRNbKv1pOSOY7Zr25g8jAHqtyhUjFkw3i
7jD5Y9IcYu+OuA=;Path=/;Secure
A_COOK1=bqvRVooK7RXQMBC98EYrX1uS8IyPlaT4dSHyjXC81l
JFoZdU0ihYiDtZ893fL6hm5r2V7c+
CgfY1Ds2f6RFVGaGYe7VT4h4m27ATrl7lRZOecFprdTW
dpOQ+UG2htcauUAVuWHeqr1NL4glhrloEYQ==;Path=/;Secure;HttpOnly
Multiparts: <none>
Body:
{
"aggrementAccepted": "Y"
}
HTTP/1.1 401 Unauthorized
Content-Type: application/json
content-length: 230
{
"type": "ERROR",
"code": "A-080003",
"message": "We couldn't continue with this authorization key. Enter
a new key, then try again.",
"details": {
"responseAction": "",
"detailedDescription": "",
"additionalErrors": [
],
"additionalInfo": {
}
}
}
---Success Response for acceptance:
Request method: POST
Request URI: https://ip:port/url
Proxy: <none>
Request params: <none>
Query params: <none>
Form params: <none>
Path params: <none>
Headers: Accept=*/*
Content-Type=application/json; charset=UTF-8
Cookies: <none>
Multiparts: <none>
Body:
{
"username": "loginname",
"password": "pass",
"domain": "pass"
}
HTTP/1.1 200 OK
Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-
eval'; style-src 'self' 'unsafe-inline'
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=15768000
X-Download-Options: noopen
X-XSS-Protection: 1; mode=block
X-FRAME-OPTIONS: SAMEORIGIN
transfer-encoding: chunked
Content-Type: application/json; charset=utf-8
set-cookie: A_COOK2=p29YwlWxWXhZGO1ZgLew2/z4jWZxo3hMnkepe
JOEENILyRNbKv1pOSOY7Zr25g8jAHqtyhUjFkw3i7jD5Y9IcYu+OuA=; Path=/;
Secure
set-cookie:A_COOK1=bqvRVooK7RXQMBC98EYrX1uS8IyPlaT4dSHyjXC81l
JFoZdU0ihYiDtZ893fL6hm5r2V7c+CgfY1Ds2f6RFVGaGYe
7VT4h4m27ATrl7lRZOecFprdTWdpOQ+UG2htcauUAVuWHeqr1NL4glhrloEYQ==;
Path=/; Secure; HTTPOnly
{
"userName": "loginname",
"role": "Admins",
"appMode": "APPL",
"isRegistrationDone": false,
"exp": "2022-04-01T01:35:07.000Z",
"currentSystemTime": "2022-04-01T01:05:07.082Z"
}
acceptance....................
Request method: POST
Request URI: https://ip:port/url
Proxy: <none>
Request params: <none>
Query params: <none>
Form params: <none>
Path params: <none>
Headers: A_COOK2=p29YwlWxWXhZGO1ZgLew2/z4jWZxo3hMnkepeJOEENIL
yRNbKv1pOSOY7Zr25g8jAHqtyhUjFkw3i7jD5Y9IcYu+OuA=
Accept=*/*
Content-Type=application/json; charset=UTF-8
Cookies:A_COOK2=p29YwlWxWXhZGO1ZgLew2/z4jWZxo3hMnkepeJOEENI
LyRNbKv1pOSOY7Zr25g8jAHqtyhUjFkw3i7jD5Y9IcYu+OuA=;Path=/;Secure
A_COOK1=bqvRVooK7RXQMBC98EYrX1uS8IyPlaT4dSHyjXC81
lJFoZdU0ihYiDtZ893fL6hm5r2V7c+CgfY1Ds2f6RFVGa
GYe7VT4h4m27ATrl7lRZOecFprdTWdpOQ+UG2htcauUAV
uWHeqr1NL4glhrloEYQ==;Path=/;Secure;HttpOnly
Multiparts: <none>
Body:
{
"aggrementAccepted": "Y"
}
HTTP/1.1 204 No Content
Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-
eval'; style-src 'self' 'unsafe-inline'
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=15768000
X-Download-Options: noopen
X-XSS-Protection: 1; mode=block
X-FRAME-OPTIONS: SAMEORIGIN
Content-Type: application/json; charset=utf-8
String loginCookie2= loginResponse.getCookie("A_COOK2");
String loginCookie1= loginResponse.getCookie("A_COOK1");
.header("A_COOK2", URLEncoder.encode(loginCookie2, String.valueOf(StandardCharsets.UTF_8)))
.cookie("A_COOK1",loginCookie1).urlEncodingEnabled(true)
Used header and cookie with URLEncode and it is working now.
Related
I am currently using Krakend (https://krakend.io) API Gateway to proxy request to my backend service. One of my backend service API response is a redirect response with http 303. The redirect response looks like this below :
HTTP/1.1 303 See Other
content-length: 48
content-type: text/plain; charset=utf-8
date: Thu, 16 Jul 2020 10:25:41 GMT
location: https://www.detik.com/
vary: Accept
x-powered-by: Express
x-envoy-upstream-service-time: 17
server: istio-envoy
The problem is that, instead of returning the http 303 response to client (with location response header) as-is, Krakend is actually following the http redirect and return the response of the redirect Url, which is the html response of https://www.detik.com/.
My current krakend configuration looks like this below :
{
"version": 2,
"extra_config": {
"github_com/devopsfaith/krakend-cors": {
"allow_origins": [],
"expose_headers": [
"Content-Length",
"Content-Type",
"Location"
],
"allow_headers": [
"Content-Type",
"Origin",
"X-Requested-With",
"Accept",
"Authorization",
"secret",
"Host"
],
"max_age": "12h",
"allow_methods": [
"GET",
"POST",
"PUT"
]
},
"github_com/devopsfaith/krakend-gologging": {
"level": "ERROR",
"prefix": "[GATEWAY]",
"syslog": false,
"stdout": true,
"format": "default"
},
"github_com/devopsfaith/krakend-logstash": {
"enabled": false
}
},
"timeout": "10000ms",
"cache_ttl": "300s",
"output_encoding": "json",
"name": "api-gateway",
"port": 8080,
"endpoints": [
{
"endpoint": "/ramatestredirect",
"method": "GET",
"extra_config": {},
"output_encoding": "no-op",
"concurrent_calls": 1,
"backend": [
{
"url_pattern": "/",
"encoding": "no-op",
"sd": "static",
"extra_config": {},
"method": "GET",
"host": [
"http://ramatestredirect.default.svc.cluster.local"
],
"disable_host_sanitize": false
}
]
}
]
}
So how can I make krakend to return original http 303 response unaltered from my backend service to the client ?
Thank You
I assume that you're calling this endpoint /ramatestredirect
To get backend http status code (as you said it return 303 http status code), you can use this way:
{
"endpoint": "/ramatestredirect",
"method": "GET",
"extra_config": {},
"output_encoding": "no-op",
"concurrent_calls": 1,
"backend": [
{
"url_pattern": "/",
"encoding": "no-op",
"sd": "static",
"extra_config": {
"github.com/devopsfaith/krakend/http": {
"return_error_details": "authentication"
}
},
"method": "GET",
"host": [
"http://ramatestredirect.default.svc.cluster.local"
],
"disable_host_sanitize": false
}
]
}
So, basically with this plugin you can get the original backend http status code
"github.com/devopsfaith/krakend/http": {
"return_error_details": "authentication"
}
If you use Lura Framework (formerly known as Kraken framework), then you may have to disable redirects for your http client.
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
When I use curl it comes without any trouble:
time curl -vvv https://antivirus-static.s3.amazonaws.com/pt_BR/terms-of-use-app.txt -H "Accept: application/json, text/plain, */*" -H "maxContentLength: -1"
* Trying 52.216.24.116...
* TCP_NODELAY set
* Connected to antivirus-static.s3.amazonaws.com (52.216.24.116) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* ALPN/NPN, server did not agree to a protocol
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=*.s3.amazonaws.com,O="Amazon.com, Inc.",L=Seattle,ST=Washington,C=US
* start date: Nov 09 00:00:00 2019 GMT
* expire date: Mar 12 12:00:00 2021 GMT
* common name: *.s3.amazonaws.com
* issuer: CN=DigiCert Baltimore CA-2 G2,OU=www.digicert.com,O=DigiCert Inc,C=US
> GET /pt_BR/terms-of-use-app.txt HTTP/1.1
> Host: antivirus-static.s3.amazonaws.com
> User-Agent: curl/7.60.0
> Accept: application/json, text/plain, */*
> maxContentLength: -1
>
< HTTP/1.1 200 OK
< x-amz-id-2: sLTO+j2y3cmR/c/HRJrdTjmG17nL1fiDcczoJ/kb8CEs0ddZaSQUa1B+MJOHk1K65C/vExHTTi0=
< x-amz-request-id: 4A97D68F2C42E0E2
< Date: Thu, 21 May 2020 19:01:21 GMT
< Last-Modified: Wed, 20 May 2020 15:48:28 GMT
< ETag: "69d0be51e21257480ac0098fd7843d5f"
< Accept-Ranges: bytes
< Content-Type: text/plain
< Content-Length: 16157
< Server: AmazonS3
<
Termos e Condi�es de Uso
1. INTRODU�O E DISPOSI�ES GERAIS
1.1. Estes Termos e Condi�es de Uso ("Termos") regem o acesso e uso por toda ...
But when I do the same request with axios, an empty data is returned:
{"config": {"adapter": [Function xhrAdapter], "baseURL": "https://antivirus-static.s3.amazonaws.com/", "data": undefined, "headers": {"Accept": "application/json, text/plain, */*"}, "maxContentLength": -1, "method": "get", "timeout": 0, "transformRequest": [[Function transformRequest]], "transformResponse": [[Function transformResponse]], "url": "/pt_BR/terms-of-use-app.txt", "validateStatus": [Function validateStatus], "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN"}, "data": "", "headers": {"accept-ranges": "bytes", "content-length": "16157", "content-type": "text/plain", "date": "Thu, 21 May 2020 18:29:33 GMT", "etag": "\"69d0be51e21257480ac0098fd7843d5f\"", "last-modified": "Wed, 20 May 2020 15:48:28 GMT", "server": "AmazonS3", "x-amz-id-2": "On0uiUG3e2CpvNu/SmMFjTefCuOABMreBngxsU0hXw9wo7rRXqLOKf1X82QzTm1g9s/wSEMox5I=", "x-amz-request-id": "E7C1A12F77B537BA"}, "request": {"DONE": 4, "HEADERS_RECEIVED": 2, "LOADING": 3, "OPENED": 1, "UNSENT": 0, "_aborted": false, "_cachedResponse": undefined, "_hasError": false, "_headers": {"accept": "application/json, text/plain, */*"}, "_incrementalEvents": false, "_lowerCaseResponseHeaders": {"accept-ranges": "bytes", "content-length": "16157", "content-type": "text/plain", "date": "Thu, 21 May 2020 18:29:33 GMT", "etag": "\"69d0be51e21257480ac0098fd7843d5f\"", "last-modified": "Wed, 20 May 2020 15:48:28 GMT", "server": "AmazonS3", "x-amz-id-2": "On0uiUG3e2CpvNu/SmMFjTefCuOABMreBngxsU0hXw9wo7rRXqLOKf1X82QzTm1g9s/wSEMox5I=", "x-amz-request-id": "E7C1A12F77B537BA"}, "_method": "GET", "_requestId": null, "_response": "", "_responseType": "", "_sent": true, "_subscriptions": [], "_timedOut": false, "_trackingName": "unknown", "_url": "https://antivirus-static.s3.amazonaws.com/pt_BR/terms-of-use-app.txt", "readyState": 4, "responseHeaders": {"Accept-Ranges": "bytes", "Content-Length": "16157", "Content-Type": "text/plain", "Date": "Thu, 21 May 2020 18:29:33 GMT", "ETag": "\"69d0be51e21257480ac0098fd7843d5f\"", "Last-Modified": "Wed, 20 May 2020 15:48:28 GMT", "Server": "AmazonS3", "x-amz-id-2": "On0uiUG3e2CpvNu/SmMFjTefCuOABMreBngxsU0hXw9wo7rRXqLOKf1X82QzTm1g9s/wSEMox5I=", "x-amz-request-id": "E7C1A12F77B537BA"}, "responseURL": "https://antivirus-static.s3.amazonaws.com/pt_BR/terms-of-use-app.txt", "status": 200, "timeout": 0, "upload": {}, "withCredentials": true}, "status": 200, "statusText": undefined}
On my code, I'm already placing things inside the promise callback:
var element = this;
axios.create({
baseURL: "https://antivirus-static.s3.amazonaws.com/",
headers: {}
}).get('/pt_BR/terms-of-use-app.txt')
.then(function (response) {
console.log(response);
element.setState({agree_terms_text: response.data, init: 1});
})
.catch(function (error) {
console.error(error);
element.setState({agree_terms_text: "Error loading terms", init: 1});
})
.then(function () {
console.log("requested terms-of-use-app.txt");
});
Inside the render():
{this.state.init == 0 ? <IndicatorMessage label={translate('loading_terms')} /> : <AgreeTerms>{this.state.agree_terms_text}</AgreeTerms>}
Should I use axios differently to request public objects from AWS S3? Am I missing something on how to use axios?
The problem had nothing to do with AWS specifically. The server was responding a UTF-8 encoded file, but the file was actually encoded in Latin1.
So I converted the file with iconv, and it worked.
When I run the Web activity, it redirects this to login page and I get below as response from the web activity .. Suggestions please?
POST URL : https://abc.azuredatabricks.net/2.0/clusters/start
Body : {"cluster_id":"1234-567890-stoke123"}
{
"Response": "\n\n\n\n \n \n Databricks - Sign In\n \n \n \n\n \n\n\n\n\n\n",
"ADFWebActivityResponseHeaders": {
"x-databricks-reason-phrase": "OK",
"vary": "Accept-Encoding;User-Agent",
"strict-transport-security": "max-age=31536000; includeSubDomains; preload",
"x-content-type-options": "nosniff",
"Cache-Control": "no-store, must-revalidate, no-cache",
"Date": "Sat, 01 Feb 2020 10:00:44 GMT",
"Server": "databricks"
},
"effectiveIntegrationRuntime": "DefaultIntegrationRuntime (North Central US)",
"executionDuration": 0,
"durationInQueue": {
"integrationRuntimeQueue": 0
},
"billingReference": {
"activityType": "ExternalActivity",
"billableDuration": {
"Managed": 0.016666666666666666
}
}
}
You need to pass the bearer token in the header:
Authorization = Bearer yourtoken
Where "Authorization" is the key and "Bearer dapi1234567890" is the value.
See this article for how to generate a new token:
https://docs.databricks.com/dev-tools/api/latest/authentication.html
I am a beginner with Klarna and am trying to get started.
Using Postman, I am trying to create a Session by doing a POST to https://api-na.playground.klarna.com/payments/v1/sessions.
I am using HTTP Basic Auth.
Below is a Request & Response.
Can you help me figure out what I am doing wrong.
Request Headers:
Accept: */*
Klarna-Correlation-Id: 45021dd4-b216-417a-a8e7-85f2447a936d
User-Agent: PostmanRuntime/7.4.0
Host: api-na.playground.klarna.com
Accept-Encoding: gzip, deflate
Content-Length: 495
Content-Type: application/json
Request Body (with test data):
{
"purchase_country": "us",
"purchase_currency": "usd",
"locale": "en-US",
"order_amount": 1000,
"order_tax_amount": 0,
"order_lines": [
{
"type": "physical",
"reference": "19-402-USA",
"name": "Battery Power Pack",
"quantity": 1,
"unit_price": 1000,
"tax_rate": 0,
"total_amount": 1000,
"total_discount_amount": 0,
"total_tax_amount": 0
}
]
}
Response:
{
"error_code": "INVALID_OPERATION",
"error_messages": [
""
],
"correlation_id": "45021dd4-b216-417a-a8e7-85f2447a936d"
}
I'm trying to POST the following but I keep getting an error:
"http: error: argument REQUEST_ITEM: "with" is not a valid value"
http POST https://someurl.com fields:='{\"example-api-identifier\":\"String with spaces\"}' Token:randomnumbers
How do I escape these spaces? I'm assuming that's the issue here?
I don't personally know about powershell, but httpie should be fine with spaces without needing the := syntax
$ http POST http://httpbin.org/post example-api-identifier="String with spaces"
yields
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 413
Content-Type: application/json
Date: Sat, 01 Feb 2020 00:25:41 GMT
Server: gunicorn/19.9.0
{
"args": {},
"data": "{\"example-api-identifier\": \"String with spaces\"}",
"files": {},
"form": {},
"headers": {
"Accept": "application/json, */*",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"Content-Length": "48",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "HTTPie/1.0.0"
},
"json": {
"example-api-identifier": "String with spaces"
},
"origin": "127.0.0.1",
"url": "http://httpbin.org/post"
}