Skip to content

Instantly share code, notes, and snippets.

@ryochin
Created December 9, 2013 10:53
Show Gist options
  • Save ryochin/7870469 to your computer and use it in GitHub Desktop.
Save ryochin/7870469 to your computer and use it in GitHub Desktop.
Plack::Middleware::Auth::Digest::Proxy for Plack::App::Proxy
package Plack::Middleware::Auth::Digest::Proxy;
use 5.008001;
use strict;
use warnings;
use parent qw/Plack::Middleware::Auth::Digest/;
use URI;
our $VERSION = '0.01';
sub call {
my ($self, $env) = @_;
my $auth = $env->{HTTP_PROXY_AUTHORIZATION} or return $self->unauthorized;
if ($auth =~ /^Digest (.*)/) {
my $auth = $self->parse_challenge($1) || {};
$auth->{method} = $env->{REQUEST_METHOD};
if ($auth->{uri} ne URI->new($env->{REQUEST_URI})->path_query) {
return [ 400, ['Content-Type', 'text/plain'], [ "Bad Request" ] ];
}
my $password = $self->authenticator->($auth->{username}, $env);
if ( defined $password
&& $self->valid_nonce($auth)
&& $self->digest($password, $auth) eq $auth->{response}) {
if ($self->stale_nonce($auth)) {
return $self->unauthorized(stale => "true");
}
$env->{REMOTE_USER} = $auth->{username};
return $self->app->($env);
}
}
return $self->unauthorized;
}
sub unauthorized {
my $self = shift;
my %params = @_;
my $body = '407 Proxy Authorization required';
my $realm = $self->realm || "restricted area";
my $nonce = $self->generate_nonce(time);
my $algorithm = 'MD5';
my $qop = 'auth';
my $challenge = qq|Digest realm="$realm", nonce="$nonce", algorithm=$algorithm, qop="$qop"|;
$challenge .= qq(, stale=true) if $params{stale};
return [
407,
[
'Content-Type' => 'text/plain',
'Content-Length' => length $body,
'Proxy-Authenticate' => $challenge,
],
[ $body ],
];
}
1;
__END__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment