Question

In my Rails 2.3 app we have an admin section that is protected by basic HTTP authentication. This has worked on our production and staging environments for years. Recently I setup a new environment to demo a long-running feature branch, and to differentiate between that and the other staging server I set it to run using a custom "redesign" environment. So now my Admin::BaseController looks like this:

class Admin::BaseController < ApplicationController
  before_filter :verify_access

  def verify_access
    logger.info "\n\n-- running verify_access filter on #{RAILS_ENV}\n"
    if %w(production staging redesign).include?(RAILS_ENV)
      logger.info "\n-- should send authentication\n"
      authenticate_or_request_with_http_basic("Restricted Access") do |username, password|
        logger.info "\nauthentication received: {username}::#{password}\n"
        username == 'myusername'
        password == 'mypassword' 
      end 
    end
  end
end

For some reason, the new server ALWAYS responds Unauthorized and doesn't offer any login dialog, not even if I quit and reopen my browser, not even if I use a private browser session, not even if I specify a username in the URL (i.e. http://username@www.mysite.com/admin). It just automatically redirects me to the root and adds ?unauthorized=true to the query string, though no where in my application code is there anything that would do that.

I know it's hitting the verify_access filter, because I can see it in the log file:

Processing Admin::OrdersController#index (for xx.xx.xx.xx at 2014-05-09 05:56:59) [GET]
  Parameters: {"action"=>"index", "controller"=>"admin/orders"}

-- running verify_access filter on redesign

-- should send authentication

Filter chain halted as [:verify_access] rendered_or_redirected.
Completed in 25ms (View: 21, DB: 1) | 401 Unauthorized [http://www.mydomain.com/admin/orders]


Processing IndexController#show (for xx.xx.xx.xx at 2014-05-09 05:56:59) [GET]
  Parameters: {"action"=>"show", "controller"=>"index", "unauthenticated"=>"true"}
Rendering index/show
Completed in 30ms (View: 27, DB: 3) | 200 OK [http://www.mydomain.com/?unauthenticated=true]

In the networking panel in Chrome, the request for the admin page actually shows that it's receiving a 302 Found response from the server, even though Rails is sending a 401 Unauthorized.

GET /admin/orders HTTP/1.1
Host: www.mydomain.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: _myapp_session=xxx

HTTP/1.1 302 Found
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
Status: 302
X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.10
Location: /?unauthenticated=true
Server: nginx/0.7.65 + Phusion Passenger 2.2.10 (mod_rails/mod_rack)

The new server is a clone of the original staging server, so the architecture is exactly the same, and all the same chef recipes were used. Any ideas on what's going on here?

Était-ce utile?

La solution

Turns out HTTP Basic Auth was tripping over Devise, one of the new features in this branch. Updating my verify_access method to the following solved the problem:

def verify_access
  if %w(production staging redesign).include?(RAILS_ENV)
    authenticate_or_request_with_http_basic("Restricted Access") do |username, password|
      username == 'username' && password == 'password'
    end
  end
  warden.custom_failure! if performed?
end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top