Here is the proposed patch for this problem - we can blacklist some
user-agents and return 200 OK for them.
Author: Jan "Yenya" Kasprzak <kas@fi.muni.cz>
403 does not work with some browsers
Some browsers are confused by the 403 Forbidden status code, with which
Apache2::AuthCookie returns the login form - they display their own
error pop-up to the user, and ignore the response body which they
just received.
This patch implements a possible hot-fix, to return 200 OK for selected
User-Agent strings.
diff --git a/perllib/Apache2/AuthCookie.pm b/perllib/Apache2/AuthCookie.pm
index 4505a3f..498a720 100644
--- a/perllib/Apache2/AuthCookie.pm
+++ b/perllib/Apache2/AuthCookie.pm
@@ -7,6 +7,8 @@ BEGIN {
use strict;
+require 5.10.0; # for the defined-or operator
+
use Carp;
use CGI '3.12';
use mod_perl2 '1.99022';
@@ -19,7 +21,8 @@ use Apache2::Access;
use Apache2::Response;
use Apache2::Util;
use APR::Table;
-use Apache2::Const qw(:common M_GET HTTP_FORBIDDEN HTTP_MOVED_TEMPORARILY);
+use Apache2::Const qw(:common M_GET HTTP_FORBIDDEN HTTP_MOVED_TEMPORARILY
+ HTTP_OK);
sub recognize_user {
my ($self, $r) = @_;
@@ -331,9 +334,23 @@ sub login_form {
return SERVER_ERROR;
}
- $r->custom_response(HTTP_FORBIDDEN, $authen_script);
+ my $status = $self->login_form_status($r) // HTTP_FORBIDDEN;
+
+ $r->custom_response($status, $authen_script);
+
+ return $status;
+}
+
+sub login_form_status {
+ my ($self, $r) = @_;
+
+ my $user_agent = $r->headers_in()->get('User-Agent')
+ or return undef;
+
+ return HTTP_OK
+ if $user_agent =~ qr!\AMozilla/5\.0 \(SymbianOS/!;
- return HTTP_FORBIDDEN;
+ return undef;
}
sub satisfy_is_valid {
@@ -896,6 +913,24 @@ specified with the C<PerlSetVar WhatEverLoginScript> configuration
directive. You can overwrite this method to provide your own
mechanism.
+=item * login_form_status($self, $r)
+
+This method returns the custom HTTP status code with which should the
+login form be returned. The default behavior (or when undef is returned
+from this method) is to use HTTP_FORBIDDEN (403) status.
+However, this confuses some browsers enough to require a different
+status code for them. By default we return HTTP_OK for Symbian phones,
+and undef for everything else.
+
+Supersede this method in a subclass to set your own return codes.
+It is also possible to call ->SUPER::login_form_status($r) from
+a subclass, to use whatever defined-values it returns, and to handle
+only the cases where undef is returned from this method.
+
+Note that HTTP_FORBIDDEN should work for most browsers, and does not
+lead the browser into a false assumption that it has successfully
+obtained the page it has originally requested.
+
=item * logout()
This is simply a convenience method that unsets the session key for