partydrone
partydrone

Reputation: 537

Conditional HTTP Basic Authentication

I want to implement HTTP basic authentication on my staging server, but only for those outside the local network. I have a Rails 3.1 app. In application.rb, I have the following:

class ApplicationController << ActionController::Base
  http_basic_authenticate_with :realm => "Staging", :name => "user", :password => "password" if :need_authentication?

private

  def need_authentication?
    Rails.env == "staging" && request.remote_addr !~ /^192.168.0.\d{1,3}$/
  end

end

Here's the rub: even when the need_authentication? method explicitly returns false, the app still asks me to authenticate, as if it's completely ignoring the if clause at the end.

So, is there any way to only require authentication under certain conditions?

Upvotes: 6

Views: 5122

Answers (2)

Dingle
Dingle

Reputation: 2452

In Rails 4, the :if condition works. For example,

class ApplicationController < ApplicationController::Base
  http_basic_authenticate_with name: "user", password: "password" if Rails.env == 'staging'
end

or if you want a helper method to set the condition,

class ApplicationController < ApplicationController::Base
  http_basic_authenticate_with name: "user", password: "password", if: :need_authentication?

  private
  def need_authentication?
    Rails.env == 'staging'
  end
end

Upvotes: 7

partydrone
partydrone

Reputation: 537

This is what worked:

class ApplicationController < ActionController::Base
  before_filter :authenticate_if_staging

private

  def authenticate_if_staging
    if Rails.env == 'staging' && request.remote_addr !~ /^192.168.0.\d{1,3}$/
      authenticate_or_request_with_http_basic 'Staging' do |name, password|
        name == 'username' && password == 'secret'
      end
    end
  end
end

'Staging' is the name of the realm. This is not required, but can be used for clarification.

Upvotes: 6

Related Questions