Support Traefik forwardAuth

This commit is contained in:
Daniel Berteaud 2022-11-06 17:45:21 +01:00
parent 9834e182f5
commit fa6de8e904
2 changed files with 26 additions and 9 deletions

View File

@ -12,6 +12,21 @@ use MIME::Base64;
use URI::Escape;
use Lemonldap::NG::Common::Session;
$ENV{LLNG_HANDLER_ENGINE} ||= 'nginx';
our $reqVar = {
# Depending on the web engine using the handler, variables where the original
# host and requested URI can vary. This hashref set the variables for the supported web engine.
nginx => {
Host => 'HTTP_HOST',
Uri => 'REQUEST_URI'
},
traefik => {
Host => 'HTTP_X_FORWARDED_HOST',
Uri => 'HTTP_X_FORWARDED_URI'
}
};
# Methods that must be overloaded
sub handler {
@ -123,7 +138,7 @@ sub run {
}
# Authentication process
my $uri = $req->{env}->{REQUEST_URI};
my $uri = $req->{env}->{ $reqVar->{ $ENV{LLNG_HANDLER_ENGINE} }->{Uri} };
my ($cond);
( $cond, $protection ) = $class->conditionSub($rule) if ($rule);
@ -245,7 +260,7 @@ sub run {
# if the cookie was fetched, a log is sent by retrieveSession()
$class->updateStatus( $req, $id ? 'EXPIRED' : 'REDIRECT' );
return $class->goToPortal( $req, $req->{env}->{REQUEST_URI} );
return $class->goToPortal( $req, $req->{env}->{ $reqVar->{ $ENV{LLNG_HANDLER_ENGINE} }->{Uri} } );
}
}
@ -270,10 +285,10 @@ sub updateStatus {
my ( $class, $req, $action, $user, $url ) = @_;
my $statusPipe = $class->tsv->{statusPipe} or return;
$user ||= $req->{env}->{REMOTE_ADDR};
$url ||= $req->{env}->{REQUEST_URI};
$url ||= $req->{env}->{ $reqVar->{ $ENV{LLNG_HANDLER_ENGINE} }->{Uri} };
eval {
$statusPipe->print(
"$user => " . $req->{env}->{HTTP_HOST} . "$url $action\n" );
"$user => " . $req->{env}->{ $reqVar->{ $ENV{LLNG_HANDLER_ENGINE} }->{Host} } . "$url $action\n" );
};
}
@ -397,7 +412,7 @@ sub grant {
# @return Constant $class->FORBIDDEN
sub forbidden {
my ( $class, $req, $session, $vhost ) = @_;
my $uri = $req->{env}->{REQUEST_URI};
my $uri = $req->{env}->{ $reqVar->{ $ENV{LLNG_HANDLER_ENGINE} }->{Uri} };
my $portal = $class->tsv->{portal}->();
$portal = ( $portal =~ m#^https?://([^/]*).*# )[0];
$portal =~ s/:\d+$//;
@ -688,7 +703,7 @@ sub _isHttps {
# @return URL
sub _buildUrl {
my ( $class, $req, $s ) = @_;
my $realvhost = $req->{env}->{HTTP_HOST};
my $realvhost = $req->{env}->{ $reqVar->{ $ENV{LLNG_HANDLER_ENGINE} }->{Host} };
my $vhost = $class->resolveAlias($req);
my $_https = $class->_isHttps( $req, $vhost );
my $portString = $class->_getPort( $req, $vhost );
@ -782,7 +797,7 @@ sub cleanHeaders {
# returns vhost whose current hostname is an alias
sub resolveAlias {
my ( $class, $req ) = @_;
my $vhost = ref $req ? $req->{env}->{HTTP_HOST} : $req;
my $vhost = ref $req ? $req->{env}->{ $reqVar->{ $ENV{LLNG_HANDLER_ENGINE} }->{Host} } : $req;
$vhost =~ s/:\d+//;
return $class->tsv->{vhostAlias}->{$vhost}
@ -806,7 +821,7 @@ sub abort {
# If abort is called without a valid request, fall to die
eval {
my $uri = $req->{env}->{REQUEST_URI};
my $uri = $req->{env}->{ $reqVar->{ $ENV{LLNG_HANDLER_ENGINE} }->{Uri} };
$class->logger->error($msg);

View File

@ -8,6 +8,8 @@ use Lemonldap::NG::Handler::Server::Main;
our $VERSION = '2.1.0';
$ENV{LLNG_HANDLER_ENGINE} ||= 'nginx';
extends 'Lemonldap::NG::Handler::PSGI';
sub init {
@ -35,7 +37,7 @@ sub _run {
Lemonldap::NG::Common::PSGI::Request->new($req) );
# Transform 302 responses in 401 since Nginx refuse it
if ( $res->[0] == 302 or $res->[0] == 303 ) {
if ( ( $res->[0] == 302 or $res->[0] == 303 ) and $ENV{LLNG_HANDLER_ENGINE} eq 'nginx' ) {
$res->[0] = 401;
}
return $res;