How can I password-protect my /sidekiq route (i.e. require authentication for the Sidekiq::Web tool)?

前端 未结 8 1254
太阳男子
太阳男子 2021-02-01 00:52

I am using sidekiq in my rails application. By Default, Sidekiq can be accessed by anybody by appending \"/sidekiq\" after the url. I want to password protect / authenticate onl

相关标签:
8条回答
  • 2021-02-01 01:11

    If you're using Sorcery for authentication, here's how to use Rails routes constraints to protect certain routes.


    Copied here from the sorcery wiki for redundancy:

    This tutorial shows how to use Rails routes constraints with Sorcery gem. Thanks to @anthonator for writing it!

    First, define UserConstraint module that will be used for all constraints:

    module RouteConstraints::UserConstraint
      def current_user(request)
        User.find_by_id(request.session[:user_id])
      end
    end
    

    Then, having that module defined, you can specify specific constraint classes. In these examples, first route will work only if there's no user logged in, the second will work only for logged user who is an admin:

    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
    

    Finally, you can add the constraints to the 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
    
    0 讨论(0)
  • 2021-02-01 01:16

    Put the following into your sidekiq initializer

    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
    

    And in the routes file:

    authenticate :user do
      mount Sidekiq::Web => '/sidekiq'
    end
    
    0 讨论(0)
  • 2021-02-01 01:16

    Another option would be to add something like CanCan and special access based on roles.

    0 讨论(0)
  • 2021-02-01 01:18

    Sorry to late to the party, but Sidekiq's wiki recommends the following for Devise:

    To allow any authenticated User:

    # config/routes.rb
    authenticate :user do
      mount Sidekiq::Web => '/sidekiq'
    end
    

    To restrict access to User.admin?

    # config/routes.rb
    authenticate :user, lambda { |u| u.admin? } do
      mount Sidekiq::Web => '/sidekiq'
    end
    

    This wiki post also has many other security schemes.

    This was tested using Rails 5.1.3, Devise 4.3 and Sidekiq 5.0

    0 讨论(0)
  • 2021-02-01 01:26

    If you're using Devise (or other Warden-based authentication), you can do this, supposing you have an AdminUser model in your app.

    # 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
    
    0 讨论(0)
  • 2021-02-01 01:28

    See "Security" under https://github.com/mperham/sidekiq/wiki/Monitoring

    Sidekiq::Web uses Rack::Protection to protect your application against typical web attacks (such as CSRF, XSS, etc). Rack::Protection would invalidate your session and raise Forbidden error if it finds that your request doesn't satisfy security requirements. One of the possible situations is having your application working behind a reverse proxy and not passing important headers to it (X-Forwarded-For,X-Forwarded-Proto). Such situation and solution could be found in this article and issue #2560...

    0 讨论(0)
提交回复
热议问题