2012-02-12 5 views
4

ここで問題となるのは、Sinatra(Rack)アプリを複数のサブインスタンスに展開し、異なるサブURIでHTTP基本認証を使用して不要なアクセスを守ることです。HTTP Basic認証を使用して複数のRack/SinatraアプリケーションをPassenger(Apache上)に展開する方法は?

Sinatraアプリ自分のドメインのように:

  1. example.com/private/foo
  2. example.com/private/moo
  3. ...
  4. ...

これらのすべてへのアクセスは、Rack::Auth::Basicミドルウェアを使用したHTTP基本認証によって保護されています。

# ... 
users = {'user' => 'password'} 
use Rack::Auth::Basic, 'realm' do |username, password| 
    users.key?(username) && users[username] == password 
end 

run MyApp 

別のconfig.ruからの変更は「王国」パラメータである唯一の事:それらのすべてのためのconfig.ruは次のようになり。

ここで問題があるのは、アプリの1つにログインした後、private/fooと言うと、Chromeは他のアプリのユーザー名とパスワードの入力を求めません(private/mooなど)。すべてのインスタンスがURLによって一意に識別されるため、これは直観的ではありません。インスタンスごとに異なる資格情報を使用すると動作しますが、Chromeが各インスタンスに対して少なくとも1回は資格情報を要求してはいけませんか?私が気づいたことの1つは、インスタンスの1つに初めてログインすると、「example.com:80のサーバーにはユーザー名とパスワードが必要です」というメッセージが表示されます。私は 'example.com/private/fooリソースにはユーザー名とパスワードが必要です'と予想していました。どのように動作するはずですか?

私はHTTP Basic AuthRack::Auth::BasicソースコードとWikipediaの記事をチェックして、私の場合を助けるために何を思い付いた:(。

+0

それは、ユーザ名とパスワードを要求しませんが、* *それは何をするのでしょうか? –

+0

ユーザ名とパスワードを要求せずにログインし、別のアプリで使用した認証情報を再利用します。 – yeban

+0

URNはそれとは関係がありません。ホスト名とレルムだけが問題です。領域が異なる場合、これは機能するはずです。 –

答えて

2

基本認証では、realmパラメータがサーバーに送信されていません。サーバーができるよう、クライアントがHTTPの基本認証の実装が正しいことを確認してください:

これで問題が発生しましたChromeは他のアプリ(プライベート/ムーなど)のユーザー名とパスワードを要求しません。すべてのインスタンスがURLによって一意に識別されるため、これは直観的ではありません。

AndrewがRFCから明らかにしたように、URLはそこで役割を果たしません。しかし、 '/ foo'が保護されている場合、 '/ foo/moo'は同じ領域で保護されます。

インスタンスごとに異なる資格情報を使用することはできますが、Chromeは各インスタンスに対して少なくとも1回は資格情報を要求してはいけませんか? (デバッガツールで検査に)何が起こっているかの場面の下で

私はアプリケーションの一つに一度ログインした後、プライベート/ fooのを言う、ということで、Chromeは他のアプリに同じ認証ヘッダーを再送信し、最初に挑戦されることなく、プライベート/ムーと言う。

RFCでは、クライアントは、サーバーが最初に挑戦することなく、レルムに対して対応する承認ヘッダーを送信する可能性があることを示しています。

Chromeは、すべてのアプリケーションを同じ領域の下に置くか、同じ領域にまたがって同じ認証ヘッダーを再送信するように見えます。私はそれが期待される行動だとは思わないが、何かが欠けている可能性がある。 Firefoxは同じように動作します。とにかく、それは質問の本質ではありませんでした。

質問のテーマは、「どのようにすれば、各インスタンスごとに少なくとも1回はユーザー名とパスワードを要求するようにするのですか?基本認証が期待通りに機能していません。

ダイジェスト認証(RFC 2617を再度参照)を使用してください。 RackはRack::Auth::Digest::MD5の下にMD5アルゴリズムバージョンを実装しています。インスタンスごとに異なるopaqueを設定し、あなたが行ってもいいです:

# ... 
realm = "Description of the protected area." 
opaque = "Secret key that uniquely identifies a realm." 

users = {'user' => 'password'} 
use Rack::Auth::Digest::MD5, realm, opaque do |username| 
    users[username] 
end 

opaqueは、クライアントによって送り返され、認証要求が正しいリソースのためのものであることをサーバー側で確認することができます。 realmの仕事は本質的に記述的なようです - どの地域や資源を保護しようとしていますか?私は何をフラッシュするのですか?

RFC:http://tools.ietf.org/html/rfc2617

関連する問題