Our firm uses an application internally that serves more or less static content to all authenticated users. The application is built such that all its resources (js, css, images, html pages) are authenticated. Sadly, I can't seem to get Varnish working for caching authenticated resources. If I make the resource unauthenticated and use the following VCL configuration, things work:
backend default {
.host = "****";
.port = "****";
}
sub vcl_recv {
if (req.url ~ "^/js" || req.url ~ "^/css" || req.url ~ "^/images") {
unset req.http.cookie;
}
}
sub vcl_fetch {
if (req.url ~ "^/js" || req.url ~ "^/css" || req.url ~ "^/images") {
unset beresp.http.set-cookie;
}
}
However, I'm looking to cache despite the resource being authenticated which I understand is not Varnish's default behaviour. Trying
if (req.http.Authorization) {
return(lookup);
}
in vcl_recv hasn't helped. Unsetting Authorization headers doesn't help either (application's authentication gets messed up).
I get the following varnish logs (b- backend calls still happen):
14 TxURL b /_search
14 TxHeader b Content-Type: application/x-www-form-urlencoded
15 RxURL c /_search
15 RxHeader c Content-Type: application/x-www-form-urlencoded
14 TxURL b /admin
14 TxHeader b Content-Type: application/x-www-form-urlencoded
17 RxURL c /admin
17 RxHeader c Content-Type: application/x-www-form-urlencoded
15 RxURL c /_search
15 RxHeader c Content-Type: application/x-www-form-urlencoded
17 RxURL c /admin
17 RxHeader c Content-Type: application/x-www-form-urlencoded
14 TxURL b /js/all.js?_=1385100392830
17 RxURL c /js/all.js?_=1385100392830
Adding the HTTP request and response headers:
Request Headers:
Host: ****.com
Connection: keep-alive
Authorization: Negotiate YIIVTAYGKwYBBQUCoIIVQDCCFTygMDAuBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKK
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
Referer: ****
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Response Headers:
Cache-Control: public, max-age=86400
Transfer-Encoding: chunked
Content-Type: application/x-javascript
Content-Encoding: gzip
Last-Modified: Sat, 10 Nov 2012 08:32:01 GMT
Accept-Ranges: bytes
ETag: "{6B28BC5E-71C3-4A1B-9D3C-1DA5EA161F96},2pub"
Vary: Accept-Encoding
Server: Microsoft-IIS/7.5
SPRequestGuid: 8864bca5-d7cb-4ac0-bbe8-3a64391ca70f
X-AspNet-Version: 2.0.50727
WWW-Authenticate: Negotiate oYGzMIGwoAMKAQChCwYJKoZIgvcSAQICooGbBIGYYIGVBgkqhkiG9xIBAgICAG+BhTCBgqADAgEFoQMCAQ+idjB
Persistent-Auth: true
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 14.0.0.6137
X-MS-InvokeApp: 1; RequireReadOnly
Date: Tue, 26 Nov 2013 15:43:46 GMT
Can someone please provide me a VCL config snippet that can help?
Related
I try to set a auth cookie. The ui and the data server are under different subdomains. So I need to activate CORS.
services.AddCors(options => options.AddPolicy("SubdomainDefault", builder => builder
.WithOrigins("https://ui.domain.de")
.AllowCredentials()
.AllowAnyHeader()
.Build()
));
On the same subdomain the cookie is set, but with different subdomains it is visible in the headers, but not set.
Request URL: https://server2.domain.de/...
Request Method: POST
Status Code: 200 OK
Remote Address: X.X.X.X:443
Referrer Policy: strict-origin-when-cross-origin
Response Header
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://ui.domain.de
Content-Length: 1017
Content-Type: application/json; charset=utf-8
Date: Fri, 29 Oct 2021 10:27:11 GMT
Server: Microsoft-IIS/8.5
Set-Cookie: auth=XXX; domain=.domain.de; path=/; secure; samesite=strict; httponly
Vary: Origin
X-Powered-By: ARR/3.0
Request Headers
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.9,en;q=0.8,en-US;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 0
Host: server2.domain.de
Origin: https://ui.domain.de
Pragma: no-cache
Referer: https://ui.domain.de/
sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Has anyone a idea?
Assuming your second request is actually a XMLHttpRequest you need to set the withCredentials flag, otherwise the cookies are not sent.
Here's an excerpt from https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#requests_with_credentials:
const invocation = new XMLHttpRequest();
const url = 'https://bar.other/resources/credentialed-content/';
function callOtherDomain() {
if (invocation) {
invocation.open('GET', url, true);
invocation.withCredentials = true;
invocation.onreadystatechange = handler;
invocation.send();
}
}
I have an API call on my front end application that uses Axios to make a PUT request. This works from postman but in the browser I get the 415 error. Here are the browser headers:
General
Request URL: api.example.com/foo
Request Method: OPTIONS
Status Code: 415 Unsupported Media Type
Remote Address: ip.address:443
Referrer Policy: no-referrer-when-downgrade
Response Headers
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD, OPTIONS
Access-Control-Allow-Origin: *
Content-Length: 175
Content-Type: application/problem+json; charset=utf-8
Date: Mon, 13 Jan 2020 20:03:06 GMT
Request-Context: appId=guid
Server: Microsoft-IIS/10.0
Strict-Transport-Security: max-age=2592000
X-Powered-By: ASP.NET
Request Headers
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: PUT
Cache-Control: no-cache
Connection: keep-alive
Host: api.example.com
Origin: http://localhost:3000
Pragma: no-cache
Referer: http://localhost:3000/extension
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36
My request looks like this:
const url = 'https://api.example.com/foo';
const headers = {
'Content-Type': 'application/json; charset=UTF-8'
};
const data = JSON.stringify([{"name": "SomeName","date": "2020-01-30T14:50:56.636Z"}]);
axios.put(
url,
data,
{headers: headers}
)
.then(res => {
console.log(res);
})
.catch((e) => {
console.log(e);
});
My API is a .net core application. Thank you friends!
I figured out the problem; in the API, the options handlers had some parameters (since I copy pasta'd the PUT request for options) and the browser wasn't sending the parameters in the preflight check, so I was getting 415. Once I removed the parameters, it worked fine!
I want process a POST request with axios in a vuejs project, but axios never send correct csrf cookie. My vuejs project run in dev mode on port 8080, my server (Spring Boot) on port 9090. I set correct CORS filter for localhost:8080 and 127.0.0.1:8080, OPTIONS is accepted, but I get a 403 error on my POST.
Here my code :
axios.post("http://127.0.0.1:9090/api/security/authenticate",
this.form,
{
withCredentials: true,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN'
}
).then((response) => {
console.log("Data: " + response.data);
}).catch((error) => {
console.log("post error: " + error);
});
And here the result of my OPTIONS request on chromium :
GENERAL:
Request URL: http://127.0.0.1:9090/api/security/authenticate
Request Method: OPTIONS
Status Code: 200
Remote Address: 127.0.0.1:9090
Referrer Policy: no-referrer-when-downgrade
RESPONSE HEADERS :
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: http://127.0.0.1:8080
Content-Length: 0
Date: Wed, 11 Dec 2019 21:44:07 GMT
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
REQUEST HEADERS :
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Connection: keep-alive
Host: 127.0.0.1:9090
Origin: http://127.0.0.1:8080
Referer: http://127.0.0.1:8080/login
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/78.0.3904.108 Chrome/78.0.3904.108 Safari/537.36
And my POST :
GENERAL:
Request URL: http://127.0.0.1:9090/api/security/authenticate
Request Method: POST
Status Code: 403
Remote Address: 127.0.0.1:9090
Referrer Policy: no-referrer-when-downgrade
RESPONSE HEADERS :
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://127.0.0.1:8080
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json;charset=UTF-8
Date: Wed, 11 Dec 2019 21:44:07 GMT
Expires: 0
Pragma: no-cache
Transfer-Encoding: chunked
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
REQUEST HEADERS :
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive
Content-Length: 56
Content-Type: application/json;charset=UTF-8
Cookie: XSRF-TOKEN=428229a0-b2b1-4473-ab3a-557e4dbac1b1
Host: 127.0.0.1:9090
Origin: http://127.0.0.1:8080
Referer: http://127.0.0.1:8080/login
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/78.0.3904.108 Chrome/78.0.3904.108 Safari/537.36
REQUEST PAYLOAD :
{login: "xxx", password: "xxx", rememberme: false}
login: "xxx"
password: "xxx"
rememberme: false
The CSRF cookie sent (428229a0...) is not correct. Previously in a GET request, I obtained an other CSRF token (70705d00...). Why wrong csrf cookie was sent ?
To be sure that is not the result of dev mode from vuejs, I build my project and deploy it on nginx server, but I got same result. I try also on firefox, get same error.
In package.json, axios is in version "^0.19.0", vuejs "^2.6.10".
What is wrong in my code ? Or is about configuration of my server ?
Thanks for your help!
API is being fetched from cache. This is happening only in Edge. I went through many similar questions in stackoverflow and tried everything but in vain.
I added cache related headers in Vue js
axios.defaults.headers.common['Cache-Control'] = 'private, no-cache, no-store, must-revalidate'
axios.defaults.headers.common['Expires'] = 0
axios.defaults.headers.common['Pragma'] = 'no-cache'
axios.defaults.headers.common['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT'
I also added cache headers from server side.
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
[ServiceFilter(typeof(AuthenticateFilter))]
[Produces("application/json")]
[Route("{tenant}")]
public class DashboardController : Controller
{
}
My Request headers looks like in chrome
Accept: application/json, text/plain, */*
Authorization: Token ggggggggggggggggggggg
Cache-Control: private, no-cache, no-store, must-revalidate
Expires: 0
If-Modified-Since: Mon, 26 Jul 1997 05:00:00 GMT
Origin: http://somedummy.com
Pragma: no-cache
Referer: http://somedummy.com/dashboard/sample
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
withCredentials: true
And response headers :
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://somedummy.com
Cache-Control: no-store,no-cache
Content-Type: application/json; charset=utf-8
Date: Mon, 11 Mar 2019 08:35:36 GMT
Pragma: no-cache
Strict-Transport-Security: max-age=31536000; includeSubDomains;
Transfer-Encoding: chunked
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Powered-By: ASP.NET
X-StackifyID: V1|b6841c38-3ec0-4a46-ac24-699ac8a5af0d|
X-XSS-Protection: 1; mode=block
APIs are being fetched from server in IE, chrome and safari but only in Edge it is being served from cache even though "Always refresh from server" option in developer option is selected.
I also have added meta in index.html
<meta http-equiv="expires" content="-1">
<meta http-equiv="cache-control" content="max-age=0">
<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="pragma" content="no-cache">
There are no errors in console. No preflight (OPTIONS) call going from Edge. Strange thing is when fiddler is open then APIs are being served from server in Edge.
Thanks in advance.
Your modification is a Server Response, this won't work, instead you should use headers: { Pragma: 'no-cache' }
Example:
const api = axios.create({
headers: { Pragma: 'no-cache' },
});
Or add it to the configuration
const config = {
headers: { Pragma: 'no-cache'},
params: { id: this.state.taskID }
}
axios.get("some URL", config).then(...)
I want to make google api calls to send mail via gmail.
To do that, I first make the following request to oauth server:
https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=SOMECLIENTID&access_type=offline&redirect_uri=http://localhost:63878/Default.aspx&scope=https://www.googleapis.com/auth/gmail.send
Note that in my request, I have included access_type=offline
It redirects me to POST https://accounts.google.com/AccountChooser and I login using my account, give consent, and get redirected back to this page:
HTTP/1.1 302 Moved Temporarily
Content-Type: text/html; charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Date: Wed, 01 Jun 2016 06:30:37 GMT
Location: http://localhost:63878/Default.aspx?code=4/LF9pQo8EH-SZkkDJV0ttNnVMIwjwWLgnc-H-QjLg__k#
Content-Language: en
Content-Encoding: gzip
as seen on fiddler.
Now using this code, I make a second call:
POST https://www.googleapis.com/oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Connection: keep-alive
Content-Length: 266
Cache-Control: no-cache
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Postman-Token: e9716588-2f62-d761-1c07-41c6dc057f0f
Accept: */*
X-Client-Data: CIm2yQEIorbJAQjEtskBCLKVygEI/ZXKAQjgmMoBCO2cygE=
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
code=4/LF9pQo8EH-SZkkDJV0ttNnVMIwjwWLgnc-H-QjLg__k#&client_id=SOMECLIENTID&client_secret=SOMESECRET&redirect_uri=http%3A%2F%2Flocalhost%3A63878%2FDefault.aspx&grant_type=authorization_code
The response I get is:
{
"access_token":"ya29.CjLzAuW07My8BHnaMaLWjhKsD2FvzI6SpUHqdqQwkugTW4lMnQl0rXt6cQdm0ir4RObYEg",
"token_type": "Bearer",
"expires_in": 3557
}
Why does this not include the refresh token in the response?