我想让我的 Plack 应用尝试几种不同的方式来授权用户。具体来说,检查用户是否已通过会话 cookie 获得授权,然后检查 Digest 身份验证,然后回退到 Basic。
我想我可以按照我希望检查它们的顺序(会话、摘要、基本)启用一堆 Auth 处理程序。不幸的是,如果摘要或基本身份验证不存在,则Plack::Middleware::Auth::Digest和Plack::Middleware::Auth::Basic的编写方式分别返回 401。
这在 Plack 通常是如何处理的?
我想让我的 Plack 应用尝试几种不同的方式来授权用户。具体来说,检查用户是否已通过会话 cookie 获得授权,然后检查 Digest 身份验证,然后回退到 Basic。
我想我可以按照我希望检查它们的顺序(会话、摘要、基本)启用一堆 Auth 处理程序。不幸的是,如果摘要或基本身份验证不存在,则Plack::Middleware::Auth::Digest和Plack::Middleware::Auth::Basic的编写方式分别返回 401。
这在 Plack 通常是如何处理的?
我没有实现,但我认为我有方法。您可以使用Plack::Middleware::Conditional做到这一点。所以它看起来像这样,但您必须填写缺少的条件/测试。我没有看到一个简单/明显的方法,但我怀疑你可能会。由于您有$env
传递的权限,您应该能够按照您想要的顺序设置/检查 HTTP_/session 内容,并为下一个处理程序保持状态以了解它是否应该启用。
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;
};
我认为您将需要编写自己的中间件,因为理想情况下(基于对RFC 2617的快速阅读)当未经过身份验证时,您将返回带有基本和摘要挑战的 WWW-Authenticate 标头(首先使用基本,对于用户只懂基本的代理)。