Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using :database_authenticatable in production, HTTP Basic Auth is used. #178

Closed
postmodern opened this issue Apr 5, 2010 · 44 comments

Comments

@postmodern
Copy link
Contributor

After deploying a fresh copy of my rails3 / devise app using :database_authenticatable, I noticed that /users/sign_in would always return an HTTP Basic Auth challenge for the "Application" realm. Although, this would not happen in development mode running under WEBrick on Ruby 1.8.7. The production server is running nginx/thin on Ruby 1.9.1.

@josevalim
Copy link
Contributor

I need more information on how to reproduce this. Devise only replies with HTTP Basic Auth if any authorization header is sent. Maybe someone is injecting those headers improperly?

@josevalim
Copy link
Contributor

Btw, these are the authorization headers:

http://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/request.rb#L213

Maybe nginx or thin are setting them to an empty string? Can you check if doing:

request.authorization.present?

In the following line:

http://github.com/plataformatec/devise/blob/master/lib/devise/failure_app.rb#L66

Fixes the issue?

@postmodern
Copy link
Contributor Author

Hmm, the beta site is currently protected with HTTP Basic Auth by nginx. Perhaps those Authentication headers are being forwarded to the Rails app?

@postmodern
Copy link
Contributor Author

Confirmed, the authorization is still present in the requests.

@postmodern
Copy link
Contributor Author

Perhaps Devise should only respond to Basic Auth for specially named Realms, such as "#{controller_name.singularize} Authentication".

@josevalim
Copy link
Contributor

I don't like to scope it to the controller name realm, but checking for the authentication realm is a good idea. What is nginx default realm?

@postmodern
Copy link
Contributor Author

http://wiki.nginx.org/NginxHttpAuthBasicModule

It does not look like it has a default Realm. There has to be a way to infer a Realm from either the Model or the routes?

@josevalim
Copy link
Contributor

Good call, I could infer the Realm from the model name. I will do so! :)

@josevalim
Copy link
Contributor

Hrm. The Realm is sent by the server and is not required to be sent by the client:

http://en.wikipedia.org/wiki/Basic_access_authentication

@josevalim
Copy link
Contributor

Ok, I fixed this. But Nginx would be a more polite citizen if he didn't forward these headers after consuming them. :)

@postmodern
Copy link
Contributor Author

Hmm, still getting Basic Auth challenges for "Application" after re-bundling and restarting the app.

@josevalim
Copy link
Contributor

:( I will investigate it more.

Are you sure you cannot change it on nginx side in the meanwhile? You can also turn HTTP Authentication off in your app.

@postmodern
Copy link
Contributor Author

For the time being I could disable the HTTP BasicAuth in Nginx, since I'm protecting everything with Devise.

@josevalim
Copy link
Contributor

Yeah, I don't know how to handle this issue besides removing Nginx or Devise HTTP Auth. In Devise there is no way to know where the Authorization headers came from. :(

@postmodern
Copy link
Contributor Author

Alright, I disabled HTTP Basic Auth in Nginx and everything works. Now we know.

@halo
Copy link

halo commented Apr 12, 2010

Amazing that someone ran into the exact same problem as I :) But I need some sort of protection for the whole site. I guess I will quickly hack some weird global cookie-based authentication before_filter (even though that's not gonna work with the API I'm trying to provide). Anyway, thanks for your quick response @josevalim.

@josevalim
Copy link
Contributor

Can I ask for one of you guys to add this to the Wiki? Something with title "Devise and Nginx" telling how to disable Devise's behavior would work great. It would help other people that may find this issue.

Thanks! :)

@halo
Copy link

halo commented Apr 12, 2010

http://github.com/plataformatec/devise/wikis/devise-and-http-authentication

(I hope that I am not mistaken when I write that HTTP Auth can't be turned off in devise.)

All the best

@jkraemer
Copy link

Hi,

I just had the same problem (and disabling basic auth in devise's config didn't help as it still seemed to respond to the Authorization header). Solved it by adding a custom Rack middleware that removes the HTTP_AUTHORIZATION from the Rack environment:

http://gist.github.com/519273

Breaks devise http basic auth for the whole application, of course.

@josevalim
Copy link
Contributor

You can simply disable http_authentication in your config/initializers/devise.rb as well.

@jkraemer
Copy link

Oh yes I did, but it still tried to handle the authorization data... (devise 1.1.rc1, Rails 3 beta4)

@jackdempsey
Copy link
Contributor

Yep, pretty sure I'm seeing the same thing here. Unfortunately the middleware doesn't seem to be solving it for me. Probably doing something stupid; will update this if I get any good info/results. (fwiw rails 3.0.0rc, devise edge from git)

@josevalim
Copy link
Contributor

You don't need the middleware. All you need is to disable the http authentication in your config/initializers/devise.rb. Configuring your nginx/apache to not handle http authentication should handle it as well.

@jackdempsey
Copy link
Contributor

It's almost certainly something in my app or server config--I can't replicate locally, and I can't fix remotely :-)
yeah, something with nginx and this box, a non rails app is having same basic auth issues.
final update -- definitely not devise's fault, as usual. Sometimes you get cut playing on the edge....thanks for the great customer service as always Jose.

@tjpeden
Copy link

tjpeden commented Nov 8, 2010

We are having this issue as well, using Devise 1.1.3 and Rails 3.0.1, we've tried disabling http authentication in the devise config and apache and nothing seems to work. We are only having this issue with IE7 on windows. We also verified that it IS devise causing this to happen because we changed the realm in the config file and it showed the updated realm in the authentication box that pops up. Are there any specific instruction for what/how to fully disable this for apache/devise 1.1.3/Rails 3.0.1?

@josevalim
Copy link
Contributor

Could you please do:

puts request.formats

In one of these IE7 requests and paste the output here?

@tjpeden
Copy link

tjpeden commented Nov 8, 2010

Here you are, sir:

request.formats [*/*]

I hope that is more useful to you :-P

@josevalim
Copy link
Contributor

Yes, this is useful to me. :) This is actually a Rails bug, we should not have [/] in formats. Could you please do me another favor? Could you do the following in your controller as well?

puts request.env

Thanks!

@josevalim
Copy link
Contributor

Also, could you also check if adding the following line to your config/initializers/devise.rb solves the problem?

config.navigational_formats = [:all, :html]

@tjpeden
Copy link

tjpeden commented Nov 8, 2010

That does not fix it either. :-/

Thank you for your continued help!

@josevalim
Copy link
Contributor

Sorry to ask, but have you restarted the server after doing the change above? If that does not work, I am not sure what will. :(

@tjpeden
Copy link

tjpeden commented Nov 8, 2010

I restarted the rails app and it didn't work, then I tried restarting apache just to be sure, and that didn't work either. :-/

@josevalim
Copy link
Contributor

Please try this one:

config.navigational_formats = [:"/", :html]

@tjpeden
Copy link

tjpeden commented Nov 8, 2010

still no good :-/

@josevalim
Copy link
Contributor

really? :( Last one, what does "puts request.format.inspect" return?

@tjpeden
Copy link

tjpeden commented Nov 8, 2010

XP IE7:
Processing by SessionsController#current as */*

request.formats: [*/*]
Completed in 0ms

OSX Chrome:
Processing by SessionsController#current as HTML

request.formats: [text/html]
Completed in 0ms

And I did add the .inspect, but it didn't seem to change anything

@josevalim
Copy link
Contributor

Yeah. So if setting config.navigational_formats = [:"/", :html] does not fix it, I am not sure of what can fix it.

Could you please try again setting config.navigational_formats and then printing Devise.navigational_formats in a controller to be sure its values are correctly set?

@tjpeden
Copy link

tjpeden commented Nov 8, 2010

Yeah, it showed up correctly :-/

@josevalim
Copy link
Contributor

Just to make sure, you are using which Devise version?

@tjpeden
Copy link

tjpeden commented Nov 9, 2010

Devise 1.1.3

Seems it's been fixed, one of the guys I work with commented out lines 25 and 26 in failure_app.rb and that seems to have fixed it. It's not pretty, but it works

@jbarreneche
Copy link

Hi, Jose
this worked for me:
config.navigational_formats = [:"*/*", :html]

Thanks!
PS: In your comment I couldn't see the "stars", I think they where parsed as markup...

@moiristo
Copy link

moiristo commented Jan 6, 2011

jbarreneche's solution worked for me as well.

@defeated
Copy link

+1 to jbarreneche's solution, this fixed HTTP Authentication dialog from being prompted in IE8

config.navigational_formats = [:"*/*", :html]

@ashchan
Copy link

ashchan commented Jan 27, 2011

@tpeden, is it possible you have a custom mime type? Devise decides if http auth is required by checking request.format.to_sym, so if you have something like this:

Mime::Type.register_alias "text/html", :iphone

request.format will be "html", and request.format.to_sym is :iphone, so to prevent http auth you could add this:

config.navigational_formats = [:html, :iphone]

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

10 participants