如何密码保护我的/ sidekiq路由(即要求对Sidekiq :: Web工具进行身份验证)?

时间:2012-09-04 14:16:47

标签: ruby ruby-on-rails-3 redis rescue sidekiq

我在rails应用程序中使用sidekiq。 默认情况下,任何人都可以通过在网址后附加“/ sidekiq”来访问Sidekiq。 我想密码保护/验证sidekiq部分。我怎么能这样做?

8 个答案:

答案 0 :(得分:92)

将以下内容放入sidekiq初始化程序

require 'sidekiq'
require 'sidekiq/web'

Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
  [user, password] == ["sidekiqadmin", "yourpassword"]
end

在路线档案中:

authenticate :user do
  mount Sidekiq::Web => '/sidekiq'
end

答案 1 :(得分:14)

请参阅https://github.com/mperham/sidekiq/wiki/Monitoring

下的“安全性”
  

Sidekiq :: Web使用Rack::Protection来保护您的应用免受典型的网络攻击(例如CSRFXSS等)。如果发现您的请求不符合安全要求,Rack :: Protection会使您的会话无效并引发Forbidden错误。其中一种可能的情况是让您的应用程序在反向代理之后工作,而不是将重要的标头传递给它(X-Forwarded-ForX-Forwarded-Proto)。可以找到in this articleissue #2560 ...

这样的情况和解决方案

答案 2 :(得分:11)

很抱歉迟到了,但Sidekiq's wiki推荐以下设计:

允许任何经过身份验证的User

# 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

This wiki post还有许多其他安全方案。

使用Rails 5.1.3,Devise 4.3和Sidekiq 5.0

测试

答案 3 :(得分:10)

如果您正在使用Devise(或其他基于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

答案 4 :(得分:7)

如果您要滚动自己的自定义身份验证,则可以使用文档here中引用的以下示例。

# lib/admin_constraint.rb
class AdminConstraint
  def matches?(request)
    return false unless request.session[:user_id]
    user = User.find request.session[:user_id]
    user && user.admin?
  end
end

# config/routes.rb
require 'sidekiq/web'
require 'admin_constraint'
mount Sidekiq::Web => '/sidekiq', :constraints => AdminConstraint.new

答案 5 :(得分:0)

另一种选择是添加CanCan和基于角色的特殊访问。

答案 6 :(得分:0)

如果您使用Sorcery进行身份验证,则可以使用how to use Rails routes constraints来保护某些路由。

在这里从巫术维基复制以获得冗余:

本教程介绍如何在Sorcery gem中使用Rails路由约束。感谢@anthonator写作!

首先,定义将用于所有约束的printf("%s", txt); 模块:

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

答案 7 :(得分:0)

可接受的答案很好,但是我认为它可以更安全地实现,例如Sidekiq documentation mentions

要保护您的应用不受定时攻击,请使用ActiveSupport::SecurityUtils.secure_compare

此外,请使用&(不要使用&&),以免短路。

最后,使用摘要阻止长度信息泄漏(Active Support 5中的默认值为secure_compare)。

活动支持5 :由于Rails PR #24510,默认情况下,传递给secure_compare的参数将通过Digest::SHA256.hexdigest

require 'active_support/security_utils'
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
  ActiveSupport::SecurityUtils.secure_compare(user, ENV["SIDEKIQ_ADMIN_USER"]) &
    ActiveSupport::SecurityUtils.secure_compare(password, ENV["SIDEKIQ_ADMIN_PASSWORD"])
end

活动支持4

require 'active_support/security_utils'
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
  ActiveSupport::SecurityUtils.secure_compare(
    ::Digest::SHA256.hexdigest(user),
    ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_ADMIN_USER"])
  ) &
    ActiveSupport::SecurityUtils.secure_compare(
      ::Digest::SHA256.hexdigest(password),
      ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_ADMIN_PASSWORD"])
    )
end