2

私はこの問題について非常に迷っており、どこに問題があるのか​​ わからないので、あなたが私を助けてくれることを願っています.

私は symfony で HTTP BASIC 認証を行っており、Drupal ページのタグを使用して、この認証で保護されている URL にアクセスしようとしています。すべてのリクエストは Varnish に送信されます

そのようなURLでユーザー名とパスワードを指定します:

<esi:include src="http://admin:adminpass@api.dev:8081/app.php/next"/>

私のニス構成ファイルには、auth.http の次の行しかありません。

if (req.http.Authorization) {
  return (pass);
}

Symfony のバックエンドは、http 認証なしでうまく機能しており、Varnish と esi タグがない場合でも http 認証はうまく機能しています。

誰かが問題のアイデアを持っている場合は、間違っていても教えてください =)

4

1 に答える 1

5

ワニスの ESI は、指定した URL に接続しないという点で、ブラウザーの iframe やリンク タグのようには機能しません。ESI は varnish 内で新しいリクエストを開始し、ワークフロー (vcl_recv など) を通過します。

varnish が http クライアントのように動作し、URL を解析し、認証ヘッダーを設定し、ホスト ヘッダーを api.dev:8081 に設定し、新しい http 接続/要求を開始することを期待していますが、そうではありません。この場合、req.url を /app.php/next に設定して新しい req を開始し、親リソース (esi タグを含む) の要求からヘッダーを継承するか、esi タグを完全に無視する可能性があると思います。

あなたがやりたいことを達成する方法は(vcl_recvで)です:

if (req.esi_level > 0 && req.url == "/app.php/next") {
     set req.http.Authorization = "BASIC [base64 encoded admin:adminpass]"
     return (pass);
}

esiタグは次のようになります<esi:include src="/app.php/next" />

ESI リクエストを別のバックエンド サーバーにヒットさせる必要がある場合は、そのサーバーを別の名前のバックエンドとして追加する必要があります。

backend authorization_needed {
   .host = "api.dev";
   .port = "8081";
}

vcl_recv で、esi リクエストに使用するように varnish に指示します。

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);
}

バックエンドが「api.dev」とは異なる仮想ホストに応答する場合は、if ブロックに req.http.Host を設定する必要がある場合もあります。

アップデート:

基本認証はクライアントから送信され、req.http.Authorization が存在するときに return (pass) を呼び出しているため、varnish はこれらのページを ESI 処理しません。渡すときに呼び出されない vcl_fetch() で esi を明示的に有効にする必要があります。

したがって、親ページではなく ESI フラグメントの認証を渡すには、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 に追加します:

if (req.http.X-Esi-Authorization) {
    set beresp.do_esi = true;
}

最終的な効果は、親の応答がキャッシュ可能であり、esi を処理することです。esi フラグメント自体は常にクライアントの認証ヘッダーと共にバックエンドに渡されます。

于 2013-07-17T16:55:27.360 に答える