package Plack::Middleware::Auth::Basic; use strict; use parent qw(Plack::Middleware); use Plack::Util::Accessor qw( realm authenticator ); use Scalar::Util; use MIME::Base64; sub prepare_app { my $self = shift; my $auth = $self->authenticator or die 'authenticator is not set'; if (Scalar::Util::blessed($auth) && $auth->can('authenticate')) { $self->authenticator(sub { $auth->authenticate(@_) }); } elsif (ref $auth ne 'CODE') { die 'authenticator should be a code reference or an object that responds to authenticate()'; } } sub call { my($self, $env) = @_; my $auth = $env->{HTTP_AUTHORIZATION} or return $self->unauthorized; if ($auth =~ /^Basic (.*)$/) { my($user, $pass) = split /:/, (MIME::Base64::decode($1) || ":"); $pass = '' unless defined $pass; if ($self->authenticator->($user, $pass)) { $env->{REMOTE_USER} = $user; return $self->app->($env); } } return $self->unauthorized; } sub unauthorized { my $self = shift; my $body = 'Authorization required'; return [ 401, [ 'Content-Type' => 'text/plain', 'Content-Length' => length $body, 'WWW-Authenticate' => 'Basic realm="' . ($self->realm || "restricted area") . '"' ], [ $body ], ]; } 1; __END__ =head1 NAME Plack::Middleware::Auth::Basic - Simple basic authentication middleware =head1 SYNOPSIS use Plack::Builder; my $app = sub { ... }; builder { enable "Auth::Basic", authenticator => \&authen_cb; $app; }; sub authen_cb { my($username, $password) = @_; return $username eq 'admin' && $password eq 's3cr3t'; } =head1 DESCRIPTION Plack::Middleware::Auth::Basic is a basic authentication handler for Plack. =head1 CONFIGURATION =over 4 =item authenticator A callback function that takes username and password supplied and returns whether the authentication succeeds. Required. Authenticator can also be an object that responds to C method that takes username and password and returns boolean, so backends for L is perfect to use: use Authen::Simple::LDAP; enable "Auth::Basic", authenticator => Authen::Simple::LDAP->new(...); =item realm Realm name to display in the basic authentication dialog. Defaults to I. =back =head1 AUTHOR Tatsuhiko Miyagawa =head1 SEE ALSO L =cut