2016-12-15 12 views
1

tl:dr、リクエストがnginx error_pageディレクティブを使用してリダイレクトされた場合、どのようにカスタムヘッダーがこのリダイレクトと共に渡されるかを確認できます。Nginxがerror_pageリダイレクションを通じてHTTPヘッダを渡す

私は現在、nginxがLDAPサーバーに対して認証するシステムを実装しています。これは、逆プロキシとして機能します。これに基づいてhttps://www.nginx.com/blog/nginx-plus-authenticate-users/ それは、それが動作する方法は、それは、別のポート上で実行されている認証ページに要求を送信する包括的なサーバーブロックを持っている、これは戻って403または200のいずれかのクッキーの内容に基づいて送信されます。これが403の場合、ユーザーはログインページに送信されます(宛先が200の場合)。

例nginx confは次のとおりです。 場所/ { auth_request/auth-proxy;

 # redirect 401 to login form 
     error_page 401 =200 /login; 

     proxy_pass http://backend/; 
    } 

    location /login { 
     proxy_pass http://backend/login; 
     # Login service returns a redirect to the original URI 
     # and sets the cookie for the ldap-auth daemon 
     proxy_set_header X-Target $request_uri; 
    } 

    location = /auth-proxy { 
     internal; 

     # The ldap-auth daemon listens on port 8888, as set 
     # in nginx-ldap-auth-daemon.py. 
     # Change the IP address if the daemon is not running on 
     # the same host as NGINX/NGINX Plus. 
     proxy_pass http://127.0.0.1:8888; 

問題は、私は認証パートタイムアウトになり、関係なく、クッキーが有効であるかどうかの、403コードを返す変更を行った、です。しかし、私はログインページでこれが起こったことをユーザーに知らせたいので、python認証コードはX-authenticationfailヘッダーにエラー値を設定します。

これは、認証コードにタイムアウトしたCookieを送信するためにcurlを使用して確認し、ヘッダーを読み戻しました。しかし、ログインのpythonコードが呼び出されると、このヘッダは消えてしまいました。私はこれがそれを転送していないnginxのためだと思う。 "proxy_set_header X-authenticationfail $ http_x_authenticationfail;"、 "add_header X-authenticationfail" test "always"という行を追加しようとしました。 error_pageディレクティブの前に置かれますが、これは効果がありません。私も同じ場所で "proxy_pass_header X-authenticationfail"を試しましたが、これも失敗しました。

サーバブロックには「underscores_in_headers on」が設定され、「proxy_pass_request_headers on」が設定されています。ログインブロックで、 "proxy_set_header X-authenticationfail" testvalue ";"ログインpythonコードに値を与え、そこからブラウザに戻ります。

これまでにありがとうございました!

+0

単にあなたの '/ login'場所 –

+0

でproxy_set_headerのX-Authenticationfail $のsent_http_x_authenticationfail'ちょうどまだ運、 – James

+0

はさらに' auth_request_set $ falure_reason $ sent_http_x_authenticationfailを入れていない、ということを試みた '置く;'右auth_request' '下回ります。どこでも '$ falure_reason'を使う必要はありません。どうにかしてこの行の存在が私の最初の解決策を作ってくれるでしょう –

答えて

1

説明から、auth_request応答のヘッダーを1か所に保存し、このヘッダーを別の場所の次の上流に渡すことです。

$sent_http_<header name>変数の中で、要求があった場所の任意の応答のヘッダーに到達することができます。ここでの問題は、Nginxが非常にメモリ効率が良いということです。どういうわけか、場所をエスケープすることができた場合、つまり内部リダイレクトを行うと、Nginxは別のリクエストをしたり、静的ファイルを提供したり、何か他のことをしようとしています。したがって、以前の要求からのデータは無関係とみなされ、メモリを解放するために破棄されます。つまり、$sent_http_<header name>変数がある場所に接続され、その場所を離れるとすぐに変数の動作が停止します。

しかし、興味のある値を保持するメモリの領域をもう一度参照することで、これらの変数の一部を保持する方法があります。前述のように、Nginxはメモリ効率が良いため、これは可能です。変数に別のvarialbeの値を代入すると、Webサーバは本当に必要でない限り、ソース変数の値をコピーしません。代わりに、ソース変数の値が保持されているメモリ内のアドレスで、新しい変数の内部ポインタを設定します。

したがって、値が$sent_http_<header name>の新しい変数を割り当てると、応答ヘッダーが格納されるメモリ領域への参照が2つあります。また、新しい変数はこの特定の場所でのみ機能する組み込み変数の大部分とは異なり、ユーザー定義変数がサーバーコンテキストに関連付けられているため、この領域のメモリを消去しないようにします。

したがって、問題を解決するには、新しい変数を定義し、値を$sent_http_x_authenticationfailに割り当てる必要があります。

最初の選択は、setディレクティブを使用することです。しかし、それは動作しません。なぜなら、setはリクエスト処理の非常に早い段階で、リクエストが送信されて何らかのレスポンスが返される前に呼び出されるからです。

幸運にも、Nginxには特別な指示があります。これにより、新しい変数にauth_requestの値を割り当てることができます。この指令はauth_request_setです。 proxy_set_headerとそれを組み合わせるあなたが望む結果を得るでしょう:両方$falure_reason$sent_http_x_authenticationfailは今メモリの同じ領域を指しているので、あなたは同じ結果とあなたのlogin場所でこれらの変数のいずれかを使用することができ

location/{ 
    auth_request /auth-proxy; 

    # Step 1: force Nginx to preserve the response header 
    auth_request_set $falure_reason $sent_http_x_authenticationfail; 

    error_page 401 =200 /login; 
    proxy_pass http://backend/; 
} 

location /login { 
    proxy_pass http://backend/login; 
    proxy_set_header X-Target $request_uri; 

    # Step 2: pass the preserved header value to the next upstream 
    proxy_set_header X-Authenticationfail $sent_http_x_authenticationfail; 
} 

location = /auth-proxy { 
    internal; 
    proxy_pass http://127.0.0.1:8888; 
} 

注意を。

関連する問題