I am using TYK with OIDC and my backend natively supports CORS that’s why I have enabled CORS.options_passthrough. Application works fine normally if JWT is valid and I don’t get any CORS errors. But problem is after JWT expiry TYK 401 unauthorized response doesn’t contain CORS headers because of course it doesn’t proxy that request to backend. My question is can we configure headers injection or CORS only in that specific case? I know that messages can be configures using Tyk Gateway Configuration Options but can we fully customize OIDC error response headers using configurations?
My API definition file is:
{
"name":"backend - OIDC",
"api_id":"4",
"org_id":"1",
"version_data": {
"not_versioned": true,
"versions": {
"Default": {
"name": "Default",
"use_extended_paths": true
}
}
},
"use_openid": true,
"openid_options": {
"providers": [
{
"issuer": "https://auth.somedomain.me/auth/realms/somerealm",
"client_ids": {
"dHlrLXRlc3Q=": "admin"
}
}
],
"segregate_by_client": false
},
"CORS": {
"options_passthrough": true,
"debug": true
},
"proxy":{
"listen_path":"/backend-oidc/",
"target_url": "http://backend",
"strip_listen_path":true
},
"active":true
}
Related:
I am trying to set up Tyk to use it with my next project and so far I think it’s a really good software. I did set up OIDC with Keycloak successfully and I am happy it was pretty simple to do so (I think you could mention somewhere that the auth token AUD field must contain the client ID though to make things even simpler).
To do some testing I did put a website that serves HTML behind Tyk + OpenID authentication. Now I want to modify the default Tyk unauthenticated response:
{
"error": "K…
opened 01:39PM - 02 Mar 18 UTC
bug
help wanted
customer request
manage-squad
When `Enable CORS: false` and `Options Passthrough: true`. In the scenario where… the gateway is short-circuiting the proxy, for example due to failed auth, the response headers do not contain required CORS headers.
It is expected by Browsers that the *SAME* CORS headers returned from an OPTIONS request will be returned on a POST request for example.
Steps to Recreate:
Browser sends preflight `OPTIONS` request to GW, GW transparently reverse proxy preflight request to upstream. CORS headers returned.
```
$ curl -X OPTIONS https://tyk-gateway.dev:8080/httpbin/post -H 'Origin: abc.com' -k -v
> OPTIONS /httpbin/post HTTP/1.1
> Host: tyk-gateway.dev:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Origin: abc.com
>
< HTTP/1.1 200 OK
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
< Access-Control-Allow-Origin: abc.com
< Access-Control-Max-Age: 3600
< Allow: POST, OPTIONS
< Connection: close
< Content-Length: 0
< Content-Type: text/html; charset=utf-8
< Date: Fri, 02 Mar 2018 13:15:42 GMT
< Server: meinheld/0.6.1
< Via: 1.1 vegur
< X-Powered-By: Flask
< X-Processed-Time: 0
< X-Ratelimit-Limit: 0
< X-Ratelimit-Remaining: 0
< X-Ratelimit-Reset: 0
<
```
Browser sends actual request to Gateway. But with invalid credentials - which means 4xx failure.
```
$ curl -X POST https://tyk-gateway.dev:8080/httpbin/post -H 'Origin: abc.com' -H 'Authorization: Bearer JUNK' -k -v
> POST /httpbin/post HTTP/1.1
> Host: tyk-gateway.dev:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Origin: abc.com
> Authorization: Bearer JUNK
>
< HTTP/1.1 403 Forbidden
< Content-Type: application/json
< Date: Fri, 02 Mar 2018 13:18:32 GMT
< Content-Length: 37
<
{
"error": "Key not authorized"
}
```
This is because the gateway has short-circuited the connection and never hits the upstream in order to get the CORS headers.
Possible Workarounds / Thoughts / Considerations:
**1. Enable CORS in the gateway as well as options_passthrough.**
This will enable, in the event of a non-simple and non-options request for Tyk to return it's own CORS headers.
```
$ curl -X POST https://tyk-gateway.dev:8080/httpbin/post -H 'Origin: https://abc.com' -H 'Authorization: Bearer JUNK' -k -v
> POST /httpbin/post HTTP/1.1
> Host: tyk-gateway.dev:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Origin: https://abc.com
> Authorization: Bearer JUNK
>
< HTTP/1.1 403 Forbidden
< Access-Control-Allow-Origin: https://abc.com
< Content-Type: application/json
< Vary: Origin
< Date: Fri, 02 Mar 2018 13:23:47 GMT
< Content-Length: 37
<
{
"error": "Key not authorized"
}
```
Pro: Simple solution.
Con: Need to configure to return exactly same CORS headers as was provided by the initial OPTIONS request, otherwise browser will complain.
**2. Given certain conditions, perform OPTIONS request to upstream and merge CORS headers with error response**
Pro: Should be correct every time
Con: Complexity from code perspective, error handling for CORS request, multiple OPTIONS requests to upstream
**3. Cache initial OPTIONS request**
When an OPTIONS request is performed, it is implied that a follow-up request will be made. For a short period of time, we can cache the headers of the preflight response.
When real request is sent, if short-circuiting, merge CORS response headers from cache with error response.
Pro: Most elegant solution
Con: Respecting CORS cache TTL, increased code complexity, possible edge cases.
Olu
March 3, 2022, 3:24pm
2
Hi @armujahid , thanks for sharing the relevant links. I will attempt to answer your questions below
My question is can we configure headers injection or CORS only in that specific case?
I guess you could with custom plugins but I haven’t tried. If it is something you have tried, can you let us know how it went.
I know that messages can be configures using Tyk Gateway Configuration Options but can we fully customize OIDC error response headers using configurations?
From what I can see in the source I think not.
I did want to ask does any of the available options as mentioned in the thread and highlighted below :
not work for you and why?
For now I am using a keyless API in front of OIDC auth API and that solution is working fine so far.