Nginx.pm 2.65 KB
Newer Older
Xavier Guimard's avatar
Xavier Guimard committed
1
# PSGI authentication package written for Nginx. It replace
Xavier Guimard's avatar
Xavier Guimard committed
2
# Lemonldap::NG::Handler::Server to manage Nginx behaviour
3
package Lemonldap::NG::Handler::Server::Nginx;
Xavier Guimard's avatar
Xavier Guimard committed
4 5 6

use strict;
use Mouse;
7
use Lemonldap::NG::Handler::Server::Main;
Xavier Guimard's avatar
Xavier Guimard committed
8

Xavier Guimard's avatar
Xavier Guimard committed
9 10
our $VERSION = '2.0.0';

Xavier Guimard's avatar
Xavier Guimard committed
11 12
extends 'Lemonldap::NG::Handler::PSGI';

13 14
sub init {
    my $self = shift;
15
    $self->api('Lemonldap::NG::Handler::Server::Main');
16
    my $tmp = $self->SUPER::init(@_);
17 18
}

19
## @method void _run()
Xavier Guimard's avatar
Xavier Guimard committed
20 21 22 23 24 25 26 27 28 29 30 31 32
# Return a subroutine that call _authAndTrace() and tranform redirection
# response code from 302 to 401 (not authenticated) ones. This is required
# because Nginx "auth_request" parameter does not accept it. The Nginx
# configuration file should transform them back to 302 using:
#
#   auth_request_set $lmlocation $upstream_http_location;
#   error_page 401 $lmlocation;
#
#@return subroutine that will be called to manage FastCGI queries
sub _run {
    my $self = shift;
    return sub {
        my $req = $_[0];
33
        $self->logger->debug('New request');
Xavier Guimard's avatar
Xavier Guimard committed
34
        my $res = $self->_authAndTrace(
35
            Lemonldap::NG::Common::PSGI::Request->new($req) );
Xavier Guimard's avatar
Xavier Guimard committed
36 37 38 39 40 41 42 43 44

        # Transform 302 responses in 401 since Nginx refuse it
        if ( $res->[0] == 302 or $res->[0] == 303 ) {
            $res->[0] = 401;
        }
        return $res;
    };
}

45
## @method PSGI-Response handler()
Xavier Guimard's avatar
Xavier Guimard committed
46 47 48 49 50 51 52 53 54 55 56 57 58
# Transform headers returned by handler main process:
# each "Name: value" is transformed to:
#  - Headername<i>: Name
#  - Headervalue<i>: value
# where <i> is an integer starting from 1
# It can be used in Nginx virtualhost configuration:
#
#    auth_request_set $headername1 $upstream_http_headername1;
#    auth_request_set $headervalue1 $upstream_http_headervalue1;
#    #proxy_set_header $headername1 $headervalue1;
#    # OR
#    #fastcgi_param $fheadername1 $headervalue1;
#
59
# LLNG::Handler::Server::Main add also a header called Lm-Remote-User set to
60 61
# whatToTrace value that can be used in Nginx virtualhost configuration to
# insert user id in logs
Xavier Guimard's avatar
Xavier Guimard committed
62 63 64 65
#
#    auth_request_set $llremoteuser $upstream_http_lm_remote_user
#
#@param $req Lemonldap::NG::Common::PSGI::Request
66
sub handler {
Xavier Guimard's avatar
Xavier Guimard committed
67
    my ( $self, $req ) = @_;
68
    my $hdrs = $req->{respHeaders};
69
    $req->{respHeaders} = [];
Xavier Guimard's avatar
Xavier Guimard committed
70
    my @convertedHdrs =
Xavier Guimard's avatar
Xavier Guimard committed
71
      ( 'Content-Length' => 0, Cookie => ( $req->env->{HTTP_COOKIE} // '' ) );
Xavier Guimard's avatar
Xavier Guimard committed
72
    my $i = 0;
Xavier Guimard's avatar
Tidy  
Xavier Guimard committed
73
    while ( my $k = shift @$hdrs ) {
74
        my $v = shift @$hdrs;
75
        if ( $k =~ /^(?:Lm-Remote-User|Cookie)$/ ) {
76
            push @convertedHdrs, $k, $v;
77 78 79
        }
        else {
            $i++;
80 81
            push @convertedHdrs, "Headername$i", $k, "Headervalue$i", $v, $k,
              $v;
82
        }
Xavier Guimard's avatar
Xavier Guimard committed
83 84 85 86 87
    }
    return [ 200, \@convertedHdrs, [] ];
}

1;