# How to Catch a Status 401 with htpasswd?

**URL:** <https://discuss.rubyonrails.org/t/how-to-catch-a-status-401-with-htpasswd/35397>\
**Category:** rubyonrails-talk\
**Created:** [October 15, 2008, 6:34pm UTC](https://discuss.rubyonrails.org/t/how-to-catch-a-status-401-with-htpasswd/35397 "2008-10-15T18:34:59Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![11175](https://avatars.discourse-cdn.com/v4/letter/1/8edcca/32.png) [@11175](https://discuss.rubyonrails.org/u/11175)\
**Post date:** [October 15, 2008, 6:34pm UTC](https://discuss.rubyonrails.org/t/how-to-catch-a-status-401-with-htpasswd/35397/1 "2008-10-15T18:34:59Z")

</div>

Hi All,

I would love to hear your thoughts on this.

I am using the htpasswd plugin located here: [http://wota.jp/svn/rails/plugins/branches/stable/htpasswd/](http://wota.jp/svn/rails/plugins/branches/stable/htpasswd/)

To validate access against a .htpasswd file. The plugin is working great but currently if you fail to get the PW correct and generate a 401 (Unauthorized) the user is presented with a completely blank page.

My goal is to at least redirect them to the home page or present a message saying their login attempts have failed.

Here is what i have tried: #application.rb &nbsp;&nbsp;rescue\_from Htpasswd::UnknownUserAccount, :with =\> :http\_status\_code

def http\_status\_code &nbsp;&nbsp;redirect\_to "[http://someplace.com](http://someplace.com)" end

^---- The above does nothing and does NOT catch anything. I have tried with Htpasswd::Error, and ActiveResource::UnauthorizedAccess -- nothing.

I have also tried a before filter with a method in application.rb calling htpasswd but i get an error saying the htpasswd method does not exist.

Any input or even a starting place where i can begin researching would be great .

THANK YOU!

---

<div class="post-metadata">

**Author:** ![11175](https://avatars.discourse-cdn.com/v4/letter/1/8edcca/32.png) [@11175](https://discuss.rubyonrails.org/u/11175)\
**Post date:** [October 17, 2008, 12:24am UTC](https://discuss.rubyonrails.org/t/how-to-catch-a-status-401-with-htpasswd/35397/2 "2008-10-17T00:24:03Z")

</div>

If anyone has a suggestion for a starting point on where I can begin trying to figure this out i'd really appreciate hearing it.

thanks

Mm Zz wrote:

---

<div class="post-metadata">

**Author:** ![Patrick\_Sullivan](https://avatars.discourse-cdn.com/v4/letter/p/53a042/32.png) [@Patrick\_Sullivan](https://discuss.rubyonrails.org/u/Patrick_Sullivan)\
**Post date:** [October 17, 2008, 12:36am UTC](https://discuss.rubyonrails.org/t/how-to-catch-a-status-401-with-htpasswd/35397/3 "2008-10-17T00:36:25Z")

</div>

In ./lib/htpasswd/auths/base.rb I found two exceptions that are raised for an invalid account and password: Htpasswd::UnknownUserAccount and Htpasswd::IncorrectPassword.

Try rescuing the latter. See if that does the trick.

---

<div class="post-metadata">

**Author:** ![Patrick\_Sullivan](https://avatars.discourse-cdn.com/v4/letter/p/53a042/32.png) [@Patrick\_Sullivan](https://discuss.rubyonrails.org/u/Patrick_Sullivan)\
**Post date:** [October 17, 2008, 12:40am UTC](https://discuss.rubyonrails.org/t/how-to-catch-a-status-401-with-htpasswd/35397/4 "2008-10-17T00:40:49Z")

</div>

Sorry for replying twice... caught this after I sent the first one.

All of your error classes are in ./lib/htpasswd/class\_methods.rb:

&nbsp;&nbsp;class Error \< StandardError; end &nbsp;&nbsp;class HeaderNotFound \< Error; end &nbsp;&nbsp;class UnknownSchemeError \< Error; end &nbsp;&nbsp;class NotAuthorizedError \< Error; end &nbsp;&nbsp;class ConfigurationError \< Error; end

&nbsp;&nbsp;class UnknownAccessControl \< ConfigurationError; end &nbsp;&nbsp;class AuthSchemesNotDefined \< ConfigurationError; end &nbsp;&nbsp;class IncorrectPassword \< NotAuthorizedError; end &nbsp;&nbsp;class UnknownUserAccount \< NotAuthorizedError; end

There's your two classes at the bottom. I would suggest rescuing Htpasswd::NotAuthorizedError, so that you catch both incorrect passwords and unknown accounts. That would be a more secure way to go, so you don't inadvertently reveal which user accounts are valid.

---

<div class="post-metadata">

**Author:** ![11175](https://avatars.discourse-cdn.com/v4/letter/1/8edcca/32.png) [@11175](https://discuss.rubyonrails.org/u/11175)\
**Post date:** [October 18, 2008, 11:12pm UTC](https://discuss.rubyonrails.org/t/how-to-catch-a-status-401-with-htpasswd/35397/5 "2008-10-18T23:12:00Z")

</div>

Hi Patrick,

Thank you so much for taking the time to look into the plugin's code and offering advice.

I gave it a shot and it appears my rescue\_from is being ignored:

This is what i have in application.rb (just for testing)

&nbsp;&nbsp;##application.rb &nbsp;&nbsp;rescue\_from Htpasswd::NotAuthorizedError, :with =\> :badlogin &nbsp;&nbsp;def badlogin &nbsp;&nbsp;&nbsp;&nbsp;redirect\_to "[http://www.google.com](http://www.google.com)" &nbsp;&nbsp;end

when the pw box comes up, i put in bad login info... and it just loops infinitely prompting me with the login/pw fields.

In my server log i have this over and over:

Processing PostsController#index (for 127.0.0.1 at 2008-10-18 15:54:41) [GET] &nbsp;&nbsp;Session ID: BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo SGFzaHsABjoKQHVzZWR7AA==--b13da02c3dcb245cb43911897a5d940881991d88 &nbsp;&nbsp;Parameters: {"action"=\>"index", "controller"=\>"posts"} Htpasswd is enabled with {:schemes=\>#\<Set: {:basic}\>} Htpasswd accepts authorization header: 'Basic YXdlZmF3ZWY6' Htpasswd error(Htpasswd::UnknownUserAccount): Htpasswd::UnknownUserAccount Htpasswd sending authenticate header: 'Basic realm="Authorization"' Filter chain halted as [:htpasswd\_authorize] rendered\_or\_redirected. Completed in 0.00386 (259 reqs/sec) | Rendering: 0.00101 (26%) | DB: 0.00000 (0%) | 401 Unauthorized [[http://localhost/posts\](http://localhost/posts%5C)]

Looking at the bottom of [http://wota.jp/svn/rails/plugins/branches/stable/htpasswd/lib/htpasswd/class\_methods.rb](http://wota.jp/svn/rails/plugins/branches/stable/htpasswd/lib/htpasswd/class_methods.rb) it appears the plugin is rescuing it's own error?

Do you think it is stepping in before my "rescue\_from"? If so, is it possible to work around that some how?

thx again.

---

<div class="post-metadata">

**Author:** ![11175](https://avatars.discourse-cdn.com/v4/letter/1/8edcca/32.png) [@11175](https://discuss.rubyonrails.org/u/11175)\
**Post date:** [October 21, 2008, 5:21pm UTC](https://discuss.rubyonrails.org/t/how-to-catch-a-status-401-with-htpasswd/35397/6 "2008-10-21T17:21:22Z")

</div>

I see the following starting on line 70 of [http://wota.jp/svn/rails/plugins/branches/stable/htpasswd/lib/htpasswd/class\_methods.rb](http://wota.jp/svn/rails/plugins/branches/stable/htpasswd/lib/htpasswd/class_methods.rb) :

&nbsp;&nbsp;rescue Htpasswd::Error =\> error &nbsp;&nbsp;&nbsp;&nbsp;logger.debug "Htpasswd error(%s): %s" % [error.class, error.message]

Since i do notice this debug statement is printed in my dev log, is it safe to say the error is rescued before my "rescue\_from" is triggered?

---

<div class="post-metadata">

**Author:** ![11175](https://avatars.discourse-cdn.com/v4/letter/1/8edcca/32.png) [@11175](https://discuss.rubyonrails.org/u/11175)\
**Post date:** [October 29, 2008, 9:01pm UTC](https://discuss.rubyonrails.org/t/how-to-catch-a-status-401-with-htpasswd/35397/7 "2008-10-29T21:01:49Z")

</div>

any takers on help with this? 🙂

thank you

---

<div class="post-metadata">

**Author:** ![11175](https://avatars.discourse-cdn.com/v4/letter/1/8edcca/32.png) [@11175](https://discuss.rubyonrails.org/u/11175)\
**Post date:** [October 30, 2008, 7:05am UTC](https://discuss.rubyonrails.org/t/how-to-catch-a-status-401-with-htpasswd/35397/8 "2008-10-30T07:05:46Z")

</div>

Mm Zz wrote:

> any takers on help with this? 🙂
> 
> thank you

Here is the solution thanks to an Awesome gent in #rubyonrails....

Since [http://wota.jp/svn/rails/plugins/branches/stable/htpasswd/lib/htpasswd/class\_methods.rb](http://wota.jp/svn/rails/plugins/branches/stable/htpasswd/lib/htpasswd/class_methods.rb) is rescuing Htpasswd::Error =\> error around line 70, i overrode the htpasswd\_authorize method by doing the following:

- Created lib/hacks/htpasswd\_hack.rb - Dropped the following into that file: module Htpasswd

&nbsp;&nbsp;protected &nbsp;&nbsp;def htpasswd\_authorize &nbsp;&nbsp;&nbsp;&nbsp;logger.debug "Htpasswd is enabled with %s" % htpasswd\_options.inspect &nbsp;&nbsp;&nbsp;&nbsp;username = Auths.scheme(self).authorize(htpasswd\_acls) &nbsp;&nbsp;&nbsp;&nbsp;logger.debug "Htpasswd authorize user '%s'" % username &nbsp;&nbsp;&nbsp;&nbsp;@htpasswd\_authorized\_username = username &nbsp;&nbsp;&nbsp;&nbsp;return true &nbsp;&nbsp;rescue Htpasswd::Error =\> error &nbsp;&nbsp;&nbsp;&nbsp;logger.debug "Htpasswd error(%s): %s" % [error.class, error.message] &nbsp;&nbsp;&nbsp;&nbsp;strongest\_auth = htpasswd\_options[:schemes].map{|scheme| Auths[scheme]}.sort.last or raise AuthSchemesNotDefined &nbsp;&nbsp;&nbsp;&nbsp;response.headers['WWW-Authenticate'] = strongest\_auth.new(htpasswd\_options).server\_header &nbsp;&nbsp;&nbsp;&nbsp;logger.debug "Htpasswd sending authenticate header: '%s'"% response.headers['WWW-Authenticate']

&nbsp;&nbsp;&nbsp;&nbsp;#render :nothing =\> true, :status =\> 401 &nbsp;&nbsp;&nbsp;&nbsp;# DO SOMETHING FANCY WITH THE 401 HERE &nbsp;&nbsp;&nbsp;&nbsp;render :action =\> "show\_home\_page", :layout=\> false , :status =\> 401 &nbsp;&nbsp;&nbsp;&nbsp;return false &nbsp;&nbsp;end

end

- In application.rb added this on line 1: require 'lib/hacks/htpasswd\_hack'

And finally i ended all that by dancing a jig.

THANKS to Patrick for responding to my help request.
