Sidekiq: Incompatibility between Rack::Session and ActionDispatch::Request::Session

Created on 28 Jul 2015  路  9Comments  路  Source: mperham/sidekiq

It looks like I'm running into this rails bug with the new 3.4.2 CSRF vulnerability fix (https://github.com/rails/rails/issues/15843).

My Test basic auth config

Sidekiq::Web.use Rack::Session::Cookie, secret: 'fake secret here'
Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
  [user, password] == ['mike perham', 'for president']
end

Anyone have a workaround suggestion?

image

Most helpful comment

There have been a lot of these issues lately, here's what we do and it works great on the latest version of Sidekiq and we're using Rails.

First, we use Google Auth for our Sidekiq endpoint. Basic auth sucks, you don't want to be typing in a username and password on your phone if you need to check Sidekiq on the go (and we wanted to get the benefit of 2FA behind our Sidekiq dashboard). We use the omniauth and omniauth-google-oauth2

In a Rails initializer, we have this code

# Setup OmniAuth
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, configatron.oauth2.google.client_id, configatron.oauth2.google.client_secret, {
           :prompt => "select_account",
  }
end
# Setup Sidekiq
Sidekiq::Web.use Rack::Session::Redis, :redis_server => configatron.redis.session_url, :expires_in => 1.hour
Sidekiq::Web.use OmniAuth::Builder do
  provider :google_oauth2, configatron.oauth2.google.sidekiq_client_id, configatron.oauth2.google.sidekiq_client_secret, {
                             :prompt => "select_account", :name => "sidekiq_google_oauth2",
                         }
end

Then we wrote an extremely small auth layer:

module Sinatra
  module GoogleOauth
    def self.registered(app)
     app.before do
        if self.session[:authenticated] || request.path_info =~ /auth/
          pass()
        end

        redirect to ('/auth/sidekiq_google_oauth2')
     end

      app.get '/auth/sidekiq_google_oauth2/callback' do
        auth = self.request.env['omniauth.auth']
        # Whitelist users who can access this in a configatron value
        if configatron.oauth2.google.sidekiq_authenticated_users.any? {|pattern| auth.info.email =~ pattern}
          self.session[:authenticated] = true
          return redirect to '/'
        else
          Rails.logger.warn{"Someone unauthorized is trying to gain access to Sidekiq: #{auth.info}"}
          return "Unauthorized user"
        end
      end

      app.get '/logout' do
        self.session.clear()
        return redirect to '/'
      end

    end
  end
  register GoogleOauth
end


module Sidekiq
  class Web
    register Sinatra::GoogleOauth
  end
end

I realize this is totally orthogonal to what you're doing, but if you find yourself unable to get it working, you can always do this setup and get the benefit of not using basic auth. :)

All 9 comments

LOL at your test data, but no clue how to fix that. Looks like an issue between Rack and Rails, not Sidekiq.

There have been a lot of these issues lately, here's what we do and it works great on the latest version of Sidekiq and we're using Rails.

First, we use Google Auth for our Sidekiq endpoint. Basic auth sucks, you don't want to be typing in a username and password on your phone if you need to check Sidekiq on the go (and we wanted to get the benefit of 2FA behind our Sidekiq dashboard). We use the omniauth and omniauth-google-oauth2

In a Rails initializer, we have this code

# Setup OmniAuth
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, configatron.oauth2.google.client_id, configatron.oauth2.google.client_secret, {
           :prompt => "select_account",
  }
end
# Setup Sidekiq
Sidekiq::Web.use Rack::Session::Redis, :redis_server => configatron.redis.session_url, :expires_in => 1.hour
Sidekiq::Web.use OmniAuth::Builder do
  provider :google_oauth2, configatron.oauth2.google.sidekiq_client_id, configatron.oauth2.google.sidekiq_client_secret, {
                             :prompt => "select_account", :name => "sidekiq_google_oauth2",
                         }
end

Then we wrote an extremely small auth layer:

module Sinatra
  module GoogleOauth
    def self.registered(app)
     app.before do
        if self.session[:authenticated] || request.path_info =~ /auth/
          pass()
        end

        redirect to ('/auth/sidekiq_google_oauth2')
     end

      app.get '/auth/sidekiq_google_oauth2/callback' do
        auth = self.request.env['omniauth.auth']
        # Whitelist users who can access this in a configatron value
        if configatron.oauth2.google.sidekiq_authenticated_users.any? {|pattern| auth.info.email =~ pattern}
          self.session[:authenticated] = true
          return redirect to '/'
        else
          Rails.logger.warn{"Someone unauthorized is trying to gain access to Sidekiq: #{auth.info}"}
          return "Unauthorized user"
        end
      end

      app.get '/logout' do
        self.session.clear()
        return redirect to '/'
      end

    end
  end
  register GoogleOauth
end


module Sidekiq
  class Web
    register Sinatra::GoogleOauth
  end
end

I realize this is totally orthogonal to what you're doing, but if you find yourself unable to get it working, you can always do this setup and get the benefit of not using basic auth. :)

Looks like @jonhyman is shooting for vice president in my administration.

:laughing:

@jonhyman Thanks for the suggestion! I know basic auth is simple, but for many users of sidekiq I imagine that is good enough.

I have always used Sidekiq Web along side a rails app, but it seems with this latest change it must run in its own process because of the rails bug I mentioned above. It would be great for us to have an out of the box solution to this.

So here is my question: Is it possible to hook Sidekiq Web onto an existing rails app using solely the sidekiq gem and basic auth?

This is a Rails 4.2 app running Sidekiq Web without issue:

https://github.com/mperham/sidekiq/tree/master/myapp

@mperham I can confirm that with your monkey patch https://github.com/rails/rails/issues/15843#issuecomment-125784043 sidekiq web is working in my rails app...:see_no_evil:...:crying_cat_face:

@mperham the example above for google auth integration assumes that Sidekiq::Web is a sinatra app. That's not the case anymore, right? Any more up-to-date solution for this? As this issue is still being linked from the wiki

@HoneyryderChuck That's a user-supplied integration. Someone else will have to supply an updated version.

Was this page helpful?
0 / 5 - 0 ratings