How to Catch a Status 401 with htpasswd?

Hi All,

I would love to hear your thoughts on this.

I am using the htpasswd plugin located here:

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:
  rescue_from Htpasswd::UnknownUserAccount, :with => :http_status_code

def http_status_code
  redirect_to ""

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

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

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


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.


Mm Zz wrote:

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

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

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

All of your error classes are in ./lib/htpasswd/class_methods.rb:

  class Error < StandardError; end
  class HeaderNotFound < Error; end
  class UnknownSchemeError < Error; end
  class NotAuthorizedError < Error; end
  class ConfigurationError < Error; end

  class UnknownAccessControl < ConfigurationError; end
  class AuthSchemesNotDefined < ConfigurationError; end
  class IncorrectPassword < NotAuthorizedError; end
  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.

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)

  rescue_from Htpasswd::NotAuthorizedError, :with => :badlogin
  def badlogin
    redirect_to ""

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 at 2008-10-18 15:54:41)
  Session ID:
  Parameters: {"action"=>"index", "controller"=>"posts"}
Htpasswd is enabled with {:schemes=>#<Set: {:basic}>}
Htpasswd accepts authorization header: 'Basic YXdlZmF3ZWY6'
Htpasswd error(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]

Looking at the bottom of
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.

I see the following starting on line 70 of

  rescue Htpasswd::Error => error
    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?

any takers on help with this? :slight_smile:

thank you

Mm Zz wrote:

any takers on help with this? :slight_smile:

thank you

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

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

  def htpasswd_authorize
    logger.debug "Htpasswd is enabled with %s" %
    username = Auths.scheme(self).authorize(htpasswd_acls)
    logger.debug "Htpasswd authorize user '%s'" % username
    @htpasswd_authorized_username = username
    return true
  rescue Htpasswd::Error => error
    logger.debug "Htpasswd error(%s): %s" % [error.class, error.message]
    strongest_auth = htpasswd_options[:schemes].map{|scheme|
Auths[scheme]}.sort.last or raise AuthSchemesNotDefined
    response.headers['WWW-Authenticate'] =
    logger.debug "Htpasswd sending authenticate header: '%s'"%

    #render :nothing => true, :status => 401
    render :action => "show_home_page", :layout=> false , :status =>
    return false


- 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.