2011-09-09 11 views
2

私はSpring Securityのremember-me機能をVarnishと連携させようとしていますが、これは信じられないほど難しいようです。通常のログインでは簡単ですが、私はちょうどj_spring_security_check URLのキャッシュをバイパスするようにワニスを設定していますが、remember-meでは任意のURLをログインのエントリポイントにすることができます。ユーザーがブラウザを開いたときに最初に気がつくのは、ワニスがスキップする(つまりキャッシュをバイパスする)URLだが、すべてうまくいくが、ユーザーがホームページ(またはそのワニスキャッシュ)にヒットした場合、ユーザーがログインしたときにCookieTheftExceptionが発生し、Remember-Me Cookieがキャンセルされるため、これ以上の自動ログインはできません。 私はそれについて考えると、これらの2つのように聞こえます(覚えていると私とワニスは一緒に働くことはできません)!これは本当ですか?Remember-me CookieとVarnish

何が間違っていた可能性がありますか?どのようにして覚えてもらえますか?私はワニスで働くことができますか?ハッシュ関数が問題になりますか?

私は(あなたはそれが関連することだと思うならば、言ってくださいハッシュ関数の定義をスキップ)の下に私のワニスのconfigsの一部を掲載しています:私はうまくhere私の最終的な実装を文書化:

sub vcl_recv { 
    # Forward IP to Apache log 
    unset req.http.X-Forwarded-For; 
    set req.http.X-Forwarded-For = client.ip; 

     if (req.http.host ~ "(?i)mysite\.com$") { 
     if (req.restarts == 0) { 
        set req.backend = mysite; 
     } 
     else { 
      error 750 "mysite"; 
     } 
    } 

    # static content should always be cached 
    if (req.url ~ "\.(js|css|gif|jpg|jpeg|png|swf|flv|txt|pdf|mp3)$") { 
     unset req.http.Cookie; 
     return(lookup); 
    } 

    # only cache "get" or "head" requests 
    if (req.request != "GET" && req.request != "HEAD") { 
     return (pass); 
    } 

    # do not cache http authentication 
    if (req.http.Authorization || req.http.Authenticate) { 
     return (pass); 
    } 

    # do not cache Spring Security URLs, esi, personal pages etc. 
     if (req.url ~ "^(/logout|/j_spring_security_check|/personal/)" || req.url ~ "\?service=esi") { 
      return(pass); 
    } 

    return (lookup); # skip default vcl_recv 
} 

sub vcl_fetch { 
    # Try again if backend not responding 
    if (beresp.status != 200 && beresp.status != 403 && beresp.status != 404 && beresp.status != 301 && beresp.status != 302 && beresp.status != 401) { 
     return(restart); 
    } 

    # block sensitive files 
    if (req.url ~ "\.(bak|conf|config|ear|exe|gz|jar|log|old|properties|tar|tmp|tgz|war)$") { 
     error 405 "Not allowed"; 
    } 

    # do esi processing for all non-static resources 
    if (req.url !~ "\.(js|css|gif|jpg|jpeg|png|swf|flv|txt|xml|html|htm|pdf|mp3|doc)$") {  
     esi; 
    } 

    # do not cache when told not to 
    if (req.http.Cache-Control ~ "no-cache") { 
     return (pass); 
    } 

    # do not cache Spring Security URLs, esi, personal pages etc. 
    if (req.url ~ "^(/logout|/j_spring_security_check|/personal/)" || req.url ~ "\?service=esi") { 
     set beresp.http.Cache-Control = "private, no-cache, no-store, must-revalidate"; 
     set beresp.http.Pragma = "no-cache"; 
     set beresp.http.Expires = "Sat, 01 Jan 2000 00:00:00 GMT"; 
     return(pass); 
    } 

    # static content should always be cached 
    if (req.url ~ "\.(js|css|gif|jpg|jpeg|png|swf|flv|txt|xml|html|htm|pdf|mp3|doc)$") { 
     unset beresp.http.set-cookie; 
     set beresp.ttl = 1h; 
    } else { 
     set beresp.ttl = 300s; 
    } 
} 

UPDATE。

答えて

2

RememberMe機能は、特別なCookieをサーバーに送信することによって機能します。サーバーはCookieの値をどのように解釈するかを知っています(たとえば、ユーザー名+パスワードはそこにエンコードされているか、ユーザーにリンクしている永続的なトークンを含んでいます)。

デフォルトでは(default.vcl)、ワニスはCookieを含むリクエストに干渉しないため、パスされます。しかし、あなたのvclファイルはリクエストクッキーを見ず、とにかくワニスに(vcl_recvの)検索を指示します。すべてのクライアントはおそらく(セッション)Cookieを持っているので、すべてのリクエストCookieを無視するのは理にかなっています。

あなたのvclファイルは、vcl_recvのrememberme要求クッキーを検出し、それに応じてパスを実行する必要があります。 (ただし、チェッククッキー名)のような何か:

if (req.http.Cookie ~ "rememberme=") { 
    return (pass); 
} 

あなたがCookieTheftExceptionsを持っておく場合は、設定-Cookieヘッダを含む任意の応答をキャッシュ場合はさらに、確認してください。この方法では、人々は同じセッションで終わります...

+1

私は同じ行に考えていましたが、Springのクッキーを持っているすべての要求に対してキャッシュをスキップしていましたので、これが私の行いました。私は成功したログイン時に追加のクッキーを追加するようにSpringを修正しました。このクッキーは一時的なものなので、ブラウザは終了時に削除されます。 REMEMBER_MEのCookieが含まれているが、この新しいCookieがないリクエストに対しては、Varnishスキップキャッシュを作成しました。このようにして、ログインの試行は元に戻されますが、それ以外の場合は定期的にキャッシュされます。ユーザーがCookieを完全に無効にすると、このルールは引き続き実行されないため、十分安全だと思われます。このアプローチについてどう思いますか? – kaqqao

+0

十分にスマートですが、これはうまくいくはずです。また、古いSESSIONID/remembermeクッキーを考慮してください。キャッシュが最適になるように、バックエンドで削除してください(期限切れのSESSIONIDや無効なRememberme Cookieなど)。 – ivy

+0

Hmmm ...私はちょうどこの事をもう一度考えています...ユーザーのREMEMBER_MEクッキーの値をハッシュ計算に単純に含めれば助けになるのでしょうか? – kaqqao

関連する問題