问题描述
我很失去了对这个问题,我不知道哪里可能是问题,所以,我希望你能帮助我。
I'm very lost on this problem, and I don't know where could be the problem, so, I hope that you could help me.
我有一个symfony HTTP基本认证方式,和我想要达到这是由该AUTH保护在一个Drupal页面的标签的网址。每个请求被发送到光油
I have an HTTP BASIC authentification with symfony, and I'm trying to reach an url which is protected by this auth, with an tag in a Drupal page. Every requests are send to a Varnish
我给像该URL的用户名和密码:
I give username and password in the url like that :
<esi:include src="http://admin:[email protected]:8081/app.php/next"/>
在我清漆的配置文件,我只有对于auth.http行:
In my varnish configuration file, I have only that lines for auth.http:
if (req.http.Authorization) {
return (pass);
}
我对Symfony的后端不含http鉴别运作良好,和HTTP认证方式运作良好时,有没有光油和ESI标签。
My backend for Symfony is working well without http authentification, and the http authentification is working well when there's not Varnish and esi tag.
如果任何人有这个问题的想法,请告诉我,即使它是错=)
If anyone have an idea of the problem, please, tell me, even if it's wrong =)
推荐答案
ESI清漆不起作用像在浏览器中的iframe或链接标记,它没有连接到你给什么网址了。 ESI刚启动一个新的请求清漆内并穿过工作流(vcl_recv等)。
ESI in varnish doesn't work like an iframe or link tag in a browser in that it doesn't connect to whatever url you give it. ESI just starts a new request within varnish and goes through the workflow (vcl_recv, etc).
您期望清漆表现得像一个HTTP客户端,解析URL,设置授权头,设置一个主机头api.dev:8081~~V和启动新的HTTP连接/请求,它不会。在这种情况下,我的猜测是它启动一个新的REQ与req.url设置为/app.php/next从父资源的请求继承头(含ESI标签),或者可能只是忽略了ESI标签完全。
You are expecting varnish to act like an http client, parsing the url, setting the authorization header, setting a host header to api.dev:8081 and initiating a new http connection/request which it will not. In this case, my guess is it starts a new req with req.url set to /app.php/next inheriting the headers from the request for the parent resource (containing the esi tag) or possibly just ignores the esi tag completely.
来完成你想做的事的方法是(在vcl_recv):
The way to accomplish what you want to do is (in vcl_recv):
if (req.esi_level > 0 && req.url == "/app.php/next") {
set req.http.Authorization = "BASIC [base64 encoded admin:adminpass]"
return (pass);
}
然后ESI标签应该类似于&LT; ESI:包括SRC =/ app.php /下一个/&GT;
如果您需要ESI要求打不同的后端服务器,则需要该服务器添加为不同的命名后端:
If you need the ESI request to hit a different backend server, you need to add that server as a different named backend:
backend authorization_needed {
.host = "api.dev";
.port = "8081";
}
和在vcl_recv,告诉清漆用它来ESI请求:
and in vcl_recv, tell varnish to use it for esi requests:
if (req.esi_level > 0 && req.url == "/app.php/next") {
set req.http.Authorization = "BASIC [base64 encoded admin:adminpass]"
set req.backend = authorization_needed;
return (pass);
}
您可能还需要设置req.http.Host中,如果块如果后端响应不同的虚拟主机不是api.dev。
you may also need to set req.http.Host in that if block if the backend responds to a different virtual host than "api.dev".
更新:
由于基本授权从客户端来了,你在呼唤回报(通)时req.http.Authorization为present,清漆不会ESI过程这些页面。你必须明确地启用vcl_fetch(ESI),当你通过不叫。
Since basic authorization is coming from the client, and you are calling return (pass) when req.http.Authorization is present, varnish will not ESI process those pages. You must explicitly enable esi in vcl_fetch() which is not called when you pass.
所以要通过授权的ESI片段,但不适用于父页面,在vcl_rev变化:
So to pass authorization for the ESI fragments but not for the parent page, change in vcl_rev:
if (req.http.Authorization && req.esi_level == 0) {
set req.http.X-Esi-Authorization = req.http.Authorization;
unset req.http.Authorization;
}
else if (req.http.X-Esi-Authorization && req.esi_level > 0 ) {
set req.http.Authorization = req.http.X-Esi-Authorization;
return (pass);
}
和添加到vcl_fetch:
And add to vcl_fetch:
if (req.http.X-Esi-Authorization) {
set beresp.do_esi = true;
}
净效果是父响应是可缓存,并将处理ESI,所述的ESI片段本身将总是被传递到与客户端的授权头后端。
The net effect is the parent response is cacheable and will process esi, the esi fragments themselves will always be passed to the backend with the client's authorization header.
这篇关于光油和ESI HTTP AUTH的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!