ruby – 如何使用Passenger(在Apache上)使用HTTP基本身份验证部署多个Rack / Sinatra应用程序?

这里的问题是使用HTTP基本身份验证在不同的子URI上部署在Passenger Apache上的相同Sinatra(Rack)应用程序的多个实例,以避免不必要的访问:

我在我的域上部署了4个Sinatra应用程序实例:

> example.com/private/foo
> example.com/private/moo
> ……
> ……

使用Rack :: Auth :: Basic中间件通过HTTP基本身份验证来保护对所有这些访问的访问. config.ru对于他们所有人看起来像:

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

run MyApp

从一个config.ru到另一个config.ru的唯一变化是’realm’参数.

现在的问题是,一旦我登录其中一个应用程序,比如private / foo,Chrome就不会提示我输入其他应用程序的用户名和密码(私人/ moo等).这是违反直觉的,因为所有实例都由其URL明确标识.为每个实例使用不同的凭据确实有效,但Chrome应该至少为每个实例请求一次凭证至少一次吗?我注意到的一件事是,当我第一次登录其中一个实例时,Chrome会说’example.com:80上的服务器需要用户名和密码’.我原以为’资源example.com/private/foo需要用户名和密码’.这不是应该如何工作?

我在HTTP Basic Auth检查了Rack :: Auth :: Basic源代码和维基百科的文章,并且没有提供任何帮助我的案例:(.

最佳答案 在基本身份验证中,realm参数不会发送回服务器.因此,服务器无法真正检查客户端是否正在为同一领域发送授权标头.这取决于客户. Rack的HTTP基本身份验证实现是正确的.所以:

Now the issue is that once I have logged into one of the apps, say private/foo, Chrome doesn’t prompt me for a username and password for other apps (private/moo etc.). This is counterintuitive since all instances are uniquiely identified by their URLs.

正如Andrew所指出的那样,从RFC中可以清楚地看到,URL并没有在那里发挥作用.但是如果’/ foo’受到保护,’/ foo / moo’在同一领域受到保护.

Using different credentials for each instance does work, but shouldn’t Chrome request credentials at least once for each instance?

在幕后发生的事情(在使用调试器工具进行检查时)是,在我一次登录到其中一个应用程序后,比如private / foo,Chrome会将相同的授权标头重新发送到其他应用程序,比如私人/ moo,没有首先受到挑战.

RFC表示客户端可以首先发送对应领域的相应授权标头,而不会受到服务器的质询.

看起来Chrome要么将我的所有应用视为同一领域,要么在不同领域重新发送相同的授权标头.我不认为这是预期的行为,但我可能会遗漏一些东西. Firefox表现相同.无论如何,这不是问题的本质.

问题的主题是“如何让Chrome为每个实例至少一次请求我的用户名和密码?基本身份验证不按我预期的方式工作;为什么?”

使用摘要式身份验证(再次使用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由客户端发回,并且可以在服务器端验证授权请求是否是正确的资源.领域的工作本质上似乎是描述性的 – 你想要保护哪个区域或资源?什么id我闪光?

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

点赞