Schwern
Schwern

Reputation: 165586

How do I stack Plack authentication handlers?

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?

Upvotes: 5

Views: 809

Answers (2)

Ashley
Ashley

Reputation: 4335

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;
};

Upvotes: 4

ysth
ysth

Reputation: 98508

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

Upvotes: 2

Related Questions