Ruby 我如何用密码保护我的/sidekiq路由(即需要sidekiq::Web工具的身份验证)?
我正在rails应用程序中使用sidekiq。 默认情况下,任何人都可以通过在url后添加“/Sidekiq”来访问Sidekiq。 我只想对sidekiq部分进行密码保护/验证。我如何才能做到这一点?请参阅下面的“安全性” Web用于保护您的应用程序免受典型的Web攻击(例如,等)。Rack::Protection将使您的会话无效,并在发现您的请求不满足安全要求时引发Ruby 我如何用密码保护我的/sidekiq路由(即需要sidekiq::Web工具的身份验证)?,ruby,ruby-on-rails-3,redis,rescue,sidekiq,Ruby,Ruby On Rails 3,Redis,Rescue,Sidekiq,我正在rails应用程序中使用sidekiq。 默认情况下,任何人都可以通过在url后添加“/Sidekiq”来访问Sidekiq。 我只想对sidekiq部分进行密码保护/验证。我如何才能做到这一点?请参阅下面的“安全性” Web用于保护您的应用程序免受典型的Web攻击(例如,等)。Rack::Protection将使您的会话无效,并在发现您的请求不满足安全要求时引发禁止的错误。其中一种可能的情况是应用程序在反向代理后工作,而不向其传递重要的头(X-Forwarded-For,X-Forwar
禁止的
错误。其中一种可能的情况是应用程序在反向代理后工作,而不向其传递重要的头(X-Forwarded-For
,X-Forwarded-Proto
)。这样的情况和解决办法是可以找到的
将以下内容放入sidekiq初始值设定项中
require 'sidekiq'
require 'sidekiq/web'
Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
# Protect against timing attacks:
# - See https://codahale.com/a-lesson-in-timing-attacks/
# - See https://thisdata.com/blog/timing-attacks-against-string-comparison/
# - Use & (do not use &&) so that it doesn't short circuit.
# - Use digests to stop length information leaking
Rack::Utils.secure_compare(::Digest::SHA256.hexdigest(user), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_USER"])) &
Rack::Utils.secure_compare(::Digest::SHA256.hexdigest(password), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_PASSWORD"]))
end
在路由文件中:
authenticate :user do
mount Sidekiq::Web => '/sidekiq'
end
如果您正在使用Desive(或其他基于Warden的身份验证),您可以这样做,假设您的应用程序中有AdminUser模型
# config/routes.rb
# This defines the authentication constraint
constraint = lambda do |request|
request.env['warden'].authenticate!({ scope: :admin_user })
end
# This mounts the route using the constraint.
# You could use any other path to make it less obvious
constraints constraint do
mount Sidekiq::Web => '/sidekiq'
end
另一个选择是添加CanCan和基于角色的特殊访问 如果您使用的是身份验证,以下是保护某些路由的方法
此处复制自巫术维基,以备冗余: 本教程演示如何将Rails路由约束与魔法宝石一起使用。谢谢你的写作 首先,定义将用于所有约束的
UserConstraint
模块:
module RouteConstraints::UserConstraint
def current_user(request)
User.find_by_id(request.session[:user_id])
end
end
然后,定义该模块后,可以指定特定的约束类。在这些示例中,第一个路由仅在没有用户登录时有效,第二个路由仅适用于作为管理员的登录用户:
class RouteConstraints::NoUserRequiredConstraint
include RouteConstraints::UserConstraint
def matches?(request)
!current_user(request).present?
end
end
class RouteConstraints::AdminRequiredConstraint
include RouteConstraints::UserConstraint
def matches?(request)
user = current_user(request)
user.present? && user.is_admin?
end
end
最后,您可以将约束添加到config/routes.rb
:
MyApp::Application.routes.draw do
# other routes …
root :to => 'admin#dashboard', :constraints => RouteConstraints::AdminRequiredConstraint.new
root :to => 'home#welcome', :constraints => RouteConstraints::NoUserRequiredConstraint.new
end
如果您正在滚动您自己的自定义身份验证,那么您可以使用文档中引用的以下示例
很抱歉,迟到了,但建议设计以下内容: 要允许任何经过身份验证的
用户
:
# config/routes.rb
authenticate :user do
mount Sidekiq::Web => '/sidekiq'
end
限制访问User.admin?
# config/routes.rb
authenticate :user, lambda { |u| u.admin? } do
mount Sidekiq::Web => '/sidekiq'
end
还有许多其他安全方案
这是使用Rails 5.1.3、Desive 4.3和Sidekiq 5.0测试的。公认的答案是好的,但我认为它可以更安全地实现,因为(在我发布之后,它被编辑以演示正确的解决方案) 要保护您的应用免受定时攻击,请使用
ActiveSupport::SecurityUtils.secure\u compare
- 看
- 看
&
(不要使用&&
),以免短路
最后,使用摘要来阻止长度信息泄漏(Active Support 5中默认的secure\u compare
)
因此,在初始化器文件中,通常在Rails项目中的config/initializers/sidekiq.rb
中,根据您的Active Support/Rails版本,编写以下代码
主动支持5+:由于,默认情况下,传递给secure\u compare
的参数将通过摘要::SHA256.hexdigest
需要“主动支持/安全措施”
需要“sidekiq”
需要“sidekiq/web”
Sidekiq::Web.use(Rack::Auth::Basic)do | user,密码|
#防止定时攻击:
#-见https://codahale.com/a-lesson-in-timing-attacks/
#-见https://thisdata.com/blog/timing-attacks-against-string-comparison/
#-使用&(不要使用&&),以免短路。
#-使用摘要阻止长度信息泄漏
ActiveSupport::SecurityUtils.secure\u compare(用户,ENV[“SIDEKIQ\u ADMIN\u用户])&
ActiveSupport::SecurityUtils.secure\u compare(密码,ENV[“SIDEKIQ\u ADMIN\u password”])
结束
主动支持4:
需要“主动支持/安全措施”
需要“sidekiq”
需要“sidekiq/web”
Sidekiq::Web.use(Rack::Auth::Basic)do | user,密码|
#防止定时攻击:
#-见https://codahale.com/a-lesson-in-timing-attacks/
#-见https://thisdata.com/blog/timing-attacks-against-string-comparison/
#-使用&(不要使用&&),以免短路。
#-使用摘要阻止长度信息泄漏
ActiveSupport::SecurityUtils.secure\u比较(
::摘要::SHA256.hexdigest(用户),
::摘要::SHA256.hexdigest(ENV[“SIDEKIQ_ADMIN_USER”])
) &
ActiveSupport::SecurityUtils.secure\u比较(
::摘要::SHA256.hexdigest(密码),
::摘要::SHA256.hexdigest(ENV[“SIDEKIQ_ADMIN_PASSWORD”])
)
结束
BTW-我将以下内容放在我的gem文件中,这样我就不必在初始化器和routes.rb文件中手动要求sidekiq和sidekiq/web:“gem'sidekiq',require:['sidekiq','sidekiq/web']”至少在我运行Rails 5的应用程序中,我没有必要用authenticate
块包装mount
调用。正如Sidekiq项目中记录的那样,您可能希望使用ActiveSupport::SecurityUtils.secure\u compare(::Digest::SHA256.hexdigest(user),::Digest::SHA256.hexdigest(ENV[“Sidekiq\u user”])和ActiveSupport::SecurityUtils.secure\u compare(::Digest::SHA256.hexdigest(密码),::Digest::SHA256.hexdigest(ENV[“SIDEKIQ_密码]))
比较用户名和密码。警告!使用=
运算符会使应用程序遭受定时攻击。任何攻击者都可以根据请求处理时间逐个猜测每个字符,最终找出密码。使用ActiveSupport::SecurityUtils.secure\u compare
,design.secure\u compare
,或类似。您不需要验证
块。如果您不使用Desive,它会在rails 6上出错。我可以将此约束放在任何其他位置吗?我的意思是,不要将其放在路由中。RB感谢Sidekiq wiki上的良好实践链接,Tom!有任何文档显示如何RSpec测试此项吗?我还没有尝试测试此with rspec。
# config/routes.rb
authenticate :user, lambda { |u| u.admin? } do
mount Sidekiq::Web => '/sidekiq'
end