Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

LABS
HTTP Basic Authentication and Devise

Say you’re using Heroku to host a staging version of your app that uses Devise for authentication. You want to keep unwanted visitors out of your staging app, but your app only uses authentication for certain features. You want to block outsiders from accessing the app entirely. Since Heroku doesn’t allow you whitelist IP addresses in your webserver config, you might want to try HTTP basic access authentication to provide top-level authentication. Doing this in Rails is pretty straightforward. Let’s assume your staging app runs in the “staging environment.”

application_controller.rb:

before_filter :authenticate if Rails.env.staging?

protected

def authenticate
    authenticate_or_request_with_http_basic do |username, password|
        username == "foo" && password == "bar"
    end
end

See Ryan Bates’ Railscast #82 HTTP Basic Authentication for more info.

This will work for most cases. However, since we have Devise installed, this won’t work. Devise will enter an infinite loop of redirects unless we tell Warden to set the performed flag.

application_controller.rb:

def authenticate
    authenticate_or_request_with_http_basic do |username, password|
        username == "foo" && password == "bar"
    end
    warden.custom_failure! if performed?
end

But wait, we’re still not done. Devise has the ability to use your HTTP Basic Authentication credentials and use it to log into its own authentication system – a cool feature if you want to be able to pass your login credentials over HTTP, perhaps as a simple way to authenticate an API consumer. However, in our case, we want to keep the HTTP Basic Authentication that we require for the entire site separate from the Devise login that we use internal to the app, so we need to disable Devise’s ability to capture our HTTP Basic Authentication credentials. In some versions of Devise, this feature is on by default, and in others it is off by default. Check your devise.rb file and make sure you have uncommented the line that disables Devise’s http_authenticatable configuration setting.

devise.rb:

config.http_authenticatable = false

Be warned that HTTP Basic Authentication transmits the username and password in clear text, so you should not use this method for applications where a higher level of security is required.

Comments
  1. chrismealy says:

    This is precisely what I needed. I was trying (and failing badly) to get deivse to play nice with the web server’s htpasswd but this is a lot simpler. The .staging? part is great. Thank you!

  2. chrismealy says:

    Rats, not actually working. I get the basic auth pop up infinite loop when a user does anything with before_filter :authenticate_user! attached.

  3. Joseph Palermo says:

    chrismealy

    Did you add:
    config.http_authenticatable = false

    to your devise config? It sounds like devise is trying to use the basic auth to log in, but of course that fails.

  4. chrismealy says:

    I did have that in there. Turns out I was using a slightly too old version of devise. I’ll give it another try …

  5. Peter Hulst says:

    exactly the problem I was having… your suggestion fixed it for me… thanks for the tip!

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *