Letting upstream handle cors requests - ambassador

I'm trying to setup a service that already handles CORS requests and would like to keep it that way instead of handling the CORS request on the Edge Proxy.
Leaving the cors field blank didn't help at all.
Is there anyway to achieve this with Ambassador?

Ambassador will not handle CORS in anyway unless you set the cors parameter in a Mapping or Module config.
Even if that is set, the way Envoy handles CORS seems to be the behavior you are searching for.
Taking a look at the linked comment in this issue https://github.com/envoyproxy/envoy/issues/300#issuecomment-296796675, we can see how Envoy chose to implement it's CORS filter. Specifically:
Assign values to the CORS headers in the repsponse: For each of the headers specified in Table 1 above:
a. let value be the option for the header config
b. if value is not defined, continue to the next header
c. else, write the response header for the specified config option
This means that Envoy will first take the value of the headers set by the upstream service and only write them with the configured values if they are not set in the response.
You can test this by creating a route to the httpbin.org (which handles CORS) and setting cors parameter in the Mapping.
---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
name: cors-httpbin
spec:
prefix: /httpbin/
service: httpbin.org
cors:
origins:
- http://foo.example
methods:
- POST
- OPTIONS
The Mapping above should configure Envoy to set the access-control-allow-origins and access-control-allow-methods headers to http://foo.example.com and POST respectively. However, after sending a test request to this endpoint, we can see that we are instead getting very different CORS headers back in the response:
curl https://aes.example.com/httpbin/headers -v -H "Origin: http://bar.example.com" -H "Access-Control-Request-Method: GET" -X OPTIONS
* Trying 34.74.58.157:443...
* Connected to aes.example.com (10.11.12.100) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: aes.example.com
* Server certificate: Let's Encrypt Authority X3
* Server certificate: DST Root CA X3
> OPTIONS /httpbin/headers HTTP/1.1
> Host: aes.example.com
> User-Agent: curl/7.69.0
> Accept: */*
> Origin: http://bar.example.com
> Access-Control-Request-Method: GET
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< date: Thu, 19 Mar 2020 13:25:48 GMT
< content-type: text/html; charset=utf-8
< content-length: 0
< server: envoy
< allow: HEAD, OPTIONS, GET
< access-control-allow-origin: http://bar.example.com
< access-control-allow-credentials: true
< access-control-allow-methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
< access-control-max-age: 3600
< x-envoy-upstream-service-time: 33
<
* Connection #0 to host aes.example.com left intact
This is because the httpbin.org upstream is setting these headers in the response and so Envoy is defaulting to using them instead of forcing the CORS configuration we gave it. In this way, Envoy really acts as a default for CORS settings and allows upstreams to set more or less restrictive configurations as they see fit.
This behavior can be confusing and caused me a lot of headaches trying to figure it out. I hope I helped clear it up for you.

Related

Does customResponseHeaders/customRequestHeaders work with key-value store (etcd)?

I set this key:
etcdctl set /production/traefik/frontends/blah/headers/customResponseHeaders/X-PoweredBy foo
But when I curl blah I don't see the header in the response.
* Rebuilt URL to: blah/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to blah (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: blah
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 34
< Content-Type: application/octet-stream
< Date: Thu, 08 Mar 2018 05:56:48 GMT
< Server: nginx/1.13.7
<
* Connection #0 to host blah left intact
I've tried many combinations of capitalization and other stuff. But I'm not even sure that the custom header stuff of traefik is supported with the key-value stores like etcd. Is it?
I know that I am successfully setting keys on the frontend I want because this works (i see it change in the dashboard):
etcdctl set /production/traefik/frontends/blah/passHostHeader false
Can I set custom header stuff using etcd or does it only work with .toml files and with Docker labels?
I found out from the slack channel that indeed custom headers are NOT supported with key-value stores like etcd. But it is planned for v1.6.

WSO2 create API for SCEP server HTTP GET POST

I have a SCEP endpoint (Simple Certificate Enrollment Protocol) which is using simple HTTP GET and POST with parameters, for example:
http://localhost/scepserver/pkiclient.exe?operation=GetCACaps&message=CA
I am trying to implement this API in WSO2 Api Manager with endpoint to my SCEP server. I was trying to do it using "Design a New REST API" but it is not working and I do not want to use JSON in message payload.
How should I define API for SCEP, with example to call endpoint with query parameters?
EDIT:
Trying through curl:
curl -X GET 'http://10.30.9.145:8280/devscep/1/pkiclient.exe?operation=GetCACaps&message=CA' -v
Result:
* Hostname was NOT found in DNS cache
* Trying 10.30.9.145...
* Connected to 10.30.9.145 (10.30.9.145) port 8280 (#0)
> GET /devscep/1/pkiclient.exe?operation=GetCACaps&message=CA HTTP/1.1
> User-Agent: curl/7.38.0
> Host: 10.30.9.145:8280
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< activityID: 22588072245075117976472
< WWW-Authenticate: realm="WSO2 API Manager"
< Content-Type: application/soap+xml; charset=UTF-8
< Date: Fri, 14 Jul 2017 13:02:16 GMT
< Transfer-Encoding: chunked
<
* Connection #0 to host 10.30.9.145 left intact
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body/></soapenv:Envelope>
In the resources section of the design page, you can define expected query parameters for each resource.
https://docs.wso2.com/display/AM210/Key+Concepts#KeyConcepts-APIresources

Cannot generate an authorization code on API Explorer

I'm trying to collect and download my lifelog user data. The first step into doing this is getting a user-access token. I am encountering problems while requesting authorization.
From the sony developer authenticization page I am told to input the following code into my API explorer:
https://platform.lifelog.sonymobile.com/oauth/2/authorize?client_id=YOUR_CLIENT_ID&scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read
I am supposed to receive the authorization code as such:
https://YOUR_CALLBACK_URL?code=abcdef
However, this is what the current situation is actually like:
I have replaced my actual client ID below with MY_CLIENT_ID for security reasons
INPUT:
GET /oauth/2/authorize?client_id=MY_CLIENT_ID&scope=lifelog.profile.read%2Blifelog.activities.read%2Blifelog.locations.read HTTP/1.1
Authorization:
Bearer kN2Kj5BThn5ZvBnAAPM-8JU0TlU
Host:
platform.lifelog.sonymobile.com
X-Target-URI:
https://platform.lifelog.sonymobile.com
Connection:
Keep-Alive
RESPONSE:
HTTP/1.1 302 Found
Content-Length:
196
Location:
https://auth.lifelog.sonymobile.com/oauth/2/authorize?scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read&client_id=MY_CLIENT_ID
Access-Control-Max-Age:
3628800
X-Amz-Cf-Id:
HILH9w3eOm-6ebs_74ghegYQyWS4xyqA1l0gXPRJuuubsoZ6eiiS3g==
Access-Control-Allow-Methods:
GET, PUT, POST, DELETE
X-Request-Id:
76caccfc976d40259ef30415d10980e9
Connection:
keep-alive
Server:
Apigee Router
X-Cache:
Miss from cloudfront
X-Powered-By:
Express
Access-Control-Allow-Headers:
origin, x-requested-with, accept
Date:
Sun, 22 Jan 2017 03:00:42 GMT
Access-Control-Allow-Origin:
*
Vary:
Accept
Via:
1.1 dc698cd00b7ec82887573cfaba9ecca6.cloudfront.net (CloudFront)
Content-Type:
text/plain; charset=utf-8
Found. Redirecting to https://auth.lifelog.sonymobile.com/oauth/2/authorize?scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read&client_id=MY_CLIENT_ID
Nowhere can I see the authorization code in the above code. I even tried copying and pasting the URL (on the last line) into my browser, it says "localhost.com took too long to respond"
This is where I input my request
I am not sure whether it is an issue with the callback URL. I don't have an actual website or app made, I just used the default localhost
I am a beginner in this and would really appreciate all help.

CouchDB Proxy Authentication Doesn't work

When I send a http request to my couchdb server like it is shown in the docs here CouchDB Proxy Authentication, it doesn't give the response shown in the docs, just empty data. What am I doing wrong?
Also, am I able to start a session with this Proxy Auth? If I try a POST /_session, I get 500 error code.
GET /_session HTTP/1.1
Host: 127.0.0.2:5984
User-Agent: curl/7.51.0
Accept: application/json
Content-Type: application/json; charset=utf-8
X-Auth-CouchDB-UserName: john
X-Auth-CouchDB-Roles: blogger
< HTTP/1.1 200 OK
< Cache-Control: must-revalidate
< Content-Length: 132
< Content-Type: application/json
< Date: Sun, 06 Nov 2016 01:10:58 GMT
< Server: CouchDB/2.0.0 (Erlang OTP/17)
<
{"ok":true,"userCtx":{"name":null,"roles":[]},"info":{"authentication_db":"_users","authentication_handlers":["cookie","default"]}}
I found in the CouchDB issue tracker that the Proxy Authentication is broken in version 2.0.0. Either that or the docs aren't updated to indicate that it only works with clusters or something. I changed back to version 1.6.1 and everything works fine. I must say that the documentation for how Proxy Authentication works is very poor.
How it works is you need your third party authentication server to have the "[couch_httpd_auth] secret" and when a client authenticates, you need to generate a HMAC-SHA1 token by combining the username and secret. Then, on any http requests you make from the client to the CouchDB server, if you include all the headers:
X-Auth-CouchDB-Roles
X-Auth-CouchDB-UserName
X-Auth-CouchDB-Token
that request will be authenticated as a user client.
Also, it is not mentioned in the docs, but POST on the /_session API using these headers does nothing.
It's not the Proxy Authentication itself which is broken in CouchDB 2.0, it's just that in the current release there's no way to configure the authentication handlers like there was in the old 1.6 days.
There are some patches mentioned in the issue tracker which add proxy authentication to the list of authentication handlers. Furthermore there was a pull request which was accepted and merged which brings back configurability to CouchDB 2.0.
However in order to take advantage of those I'm afraid you either have to wait until the next release, or build CouchDB 2.0 yourself from the sources.
Proxy authentication is fixed as of CouchDB 2.1.1. The latest (>2.1.1) documentation shows how to configure proxy authentication again, along with the important proxy_use_secret option.

Custom Status Line Not Working in RESTLET

I am writing a REST application and i am using RESTLET. My service has a PUT method. As part of the response, i would like to return to the user Custom Status.
For Example :
200 - Successfully Created and Data processing in progress.
I tried to set the statuses as below.
#Put
public String storeItem(Representation entity) throws Exception {
// Some Processing
Status st = new Status(420,null,"REASON_PHRASE","Some description",null);
setStatus(st);
return "Some String Representation"
}
When i try to access the URL using CURL, i get the following status line.
curl -v -X PUT "http://localhost:8080/extensible/data/process"
* About to connect() to localhost port 8080 (#0)
* Trying ::1... connected
* Connected to localhost (::1) port 8080 (#0)
> PUT /extensible/data/upload HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 420 420
< Content-Type: application/json; charset=UTF-8
< Date: Wed, 22 Jan 2014 06:56:24 GMT
< Accept-Ranges: bytes
< Server: Restlet-Framework/2.0.1
< Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
< Content-Length: 21
<
* Connection #0 to host localhost left intact
* Closing connection #0
The status line above is HTTP/1.1 420 420 but i expect a status line of HTTP/1.1 420 REASON_PHRASE
What am i doing wrong?
Any help will be greatly appreciated.
My two cents about the design.
1. I think you need a pretty good reason to use a custom http status.
I don't think this is the case.
REST API consumed by applications and the application that consume the API know that this particular PUT is part of an asynchronous process.
There for a simple 200 with the new id as data or link to the edit url should be enough.
The client application should notify the user, if decided to do so.
If you still think a custom status is the right way you should consider using 20* and not 420.