I would like to have my Plack app try several different means of authorizing the user. Specifically, check if the user is already authorized via a session cookie, then check for Digest authentication and then fall back to Basic.
I figured I could just enable a bunch of Auth handlers in the order I wanted them to be checked (Session, Digest, Basic). Unfortunately, the way that Plack::Middleware::Auth::Digest and Plack::Middleware::Auth::Basic are written they both return 401 if digest or basic auth doesn't exist, respectively.
How is this normally dealt with in Plack?
I do not have an implementation but I think I have the approach. You can do this "in-line" with Plack::Middleware::Conditional. So it would look like this but you'll have to fill in the missing conditions/tests. I didn't see an easy/obvious way but I suspect you might. Since you have the $env
to pass around you should be able to set/check HTTP_/session stuff in the order you want and keep the state for the next handler to know if it should be enabled or not.
use Plack::Builder;
my $app = sub {
[ 200,
[ "Content-Type" => "text/plain" ],
[ "O HAI, PLAK!" ]
];
};
builder {
enable "Session::Cookie";
enable_if { my $env = shift;
# I don't know...
} "Auth::Digest",
realm => "Secured", secret => "BlahBlah",
authenticator => sub { $_[0] eq $_[1] };
enable_if { my $env = shift;
# I don't know...
} "Auth::Basic",
authenticator => sub { $_[0] eq $_[1] };
$app;
};
I think you are going to need to write your own middleware, since ideally (based on a very quick read of RFC 2617) when not authenticated you would return a WWW-Authenticate header with both Basic and Digest challenges (with Basic first, for user agents that only understand Basic).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With