Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 473
Schwern Avatar asked Jan 11 '11 04:01

Schwern


2 Answers

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;
};
like image 65
Ashley Avatar answered Sep 20 '22 17:09

Ashley


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

like image 44
ysth Avatar answered Sep 18 '22 17:09

ysth