Как я могу защитить паролем мой / sidekiq маршрут (т. е. требовать аутентификации для Sidekiq::Web tool)?

Я использую sidekiq в своем приложении rails. По умолчанию Sidekiq может быть доступен любому, добавив "/ sidekiq " после url-адреса. Я хочу защитить паролем / аутентифицировать только часть sidekiq. Как я могу это сделать?

7 ответов


поместите следующее в свой инициализатор 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

см. раздел "Безопасность" в разделе https://github.com/mperham/sidekiq/wiki/Monitoring

Sidekiq:: Web использует Для:Защиты для защиты вашего приложения от типичных веб-атак (например,CSRF, межсайтовый скриптинг и т. д.). Rack:: защита аннулирует вашу сессию и поднимет Forbidden ошибки, если он считает, что ваш запрос не удовлетворяет требованиям безопасности. Одна из возможных ситуаций - наличие вашего приложения Работа за обратным прокси и не передача ему важных заголовков (X-Forwarded-For,X-Forwarded-Proto). Такую ситуацию и решение можно было найти в этой статье и выпуск #2560...


Если вы используете Devise (или другую аутентификацию на основе Warden), вы можете сделать это, предположив, что у вас есть модель администратора в вашем приложении.

# 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

извините за опоздание на вечеринку, но wiki Sidekiq в рекомендует следующее Для Devise:

разрешить любой аутентифицированный 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

этот пост wiki также имеет много других схем безопасности.

это было протестировано с помощью Rails 5.1.3, Devise 4.3 и Sidekiq 5.0


Если вы выполняете собственную пользовательскую аутентификацию, вы можете использовать приведенный ниже пример, на который ссылается docs здесь.

# 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

другой вариант - добавить что-то вроде CanCan и специального доступа на основе ролей.


если вы используете колдовство для аутентификации, вот как использовать ограничения Rails routes для защиты определенных маршрутов.


скопировано здесь из волшебной Вики для избыточности:

в этом уроке показано, как использовать ограничения Rails routes с волшебным камнем. Спасибо @anthonator для ее написания!

во-первых, определить 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