diff --git a/doc/sources/admin/ssoaas.rst b/doc/sources/admin/ssoaas.rst index ffee54281..9595f4cc5 100644 --- a/doc/sources/admin/ssoaas.rst +++ b/doc/sources/admin/ssoaas.rst @@ -7,7 +7,7 @@ Our concept of SSOaaS Access management provides 3 services: - Global Authentication: Single Sign-On -- Authorization: to grant authentication is not enough. User rights +- Authorization: Grant authentication is not enough. User rights must be checked - Accounting: SSO logs (access) + application logs *(transactions and results)* @@ -25,13 +25,13 @@ the ability for an app to manage authorizations and choose user attributes to set. Authentication can not be really ``*aaS``: app must just use it, not manage it. -LL::NG affords some features that can be used to provide SSO as a -service: a web application can manage its rules and headers. Docker or +LL::NG affords some features that can be used for providing SSO as a +Service: a web application can manage its rules and headers. Docker or VM images (Nginx only) includes LL::NG Nginx configuration that aims to a global :ref:`LL::NG authorization server`. By default, all authenticated users can access and one header is set: -``Auth-User``. If application gives a RULES_URL parameter that refers to +``Auth-User``. If application defines a RULES_URL parameter that refers to a JSON file, authorization server will read it, apply specified rules and set required headers (see :doc:`DevOps Handler`). @@ -64,8 +64,9 @@ Using a global FastCGI (or uWSGI) server Nginx ^^^^^ -In this example, web server templates (Nginx only) are configured to -request authorization from a central FastCGI server: +Examples below are web server templates (Nginx only) configured to +request authorization from a central FastCGI server. +With an uWSGI central server, use 'uwsgi_param' directive (Nginx only): .. code:: @@ -86,7 +87,11 @@ request authorization from a central FastCGI server: # Keep original request (LLNG server will received /lmauth) fastcgi_param X_ORIGINAL_URI $original_uri; - # Set dynamically rules (LLNG will poll it every 10 mn) + # Set redirection params + fastcgi_param HTTPS_REDIRECT "$https"; + fastcgi_param PORT_REDIRECT $server_port; + + # Set dynamically rules (LL::NG will poll it every 10 mn) fastcgi_param RULES_URL http://rulesserver/my.json; } location /rules.json { @@ -115,22 +120,22 @@ Apache ^^^^^^ There is an experimental FastCGI client in LL::NG. You just have to -install FCGI::Client and add this in the apache2.conf or your web -applications or proxies. +install LemonLDAP::NG handler and FCGI::Client. Then, add this in +your apache2.conf, web applications or reverse-proxies. The following configuration example assumes that you are in a "central FastCGI" configuration. .. code-block:: apache - + ServerName app.tls PerlHeaderParserHandler Lemonldap::NG::Handler::ApacheMP2::FCGIClient # This must point to the central FastCGI server PerlSetVar LLNG_SERVER 192.0.2.1:9090 - # Declare this vhost as a DevOps vhost, so that we do not have + # Declare this vhost as a DevOps protected vhost. So you do not have # to declare it in the LemonLDAP::NG Manager PerlSetVar VHOSTTYPE DevOps @@ -138,6 +143,8 @@ FastCGI" configuration. # used to make the authentication decision about this virtualhost # Make sure the central FastCGI server can reach it PerlSetVar RULES_URL http://app.tld/rules.json + PerlSetVar HTTPS_REDIRECT HTTPS + PerlSetVar PORT_REDIRECT SERVER_PORT ... @@ -158,6 +165,8 @@ you can protect also an Express server. Example: port: 9090, PARAMS: { RULES_URL: 'http://my-server/rules.json' + HTTPS_REDIRECT: 'ON', + PORT_REDIRECT: '443' } }); @@ -204,6 +213,8 @@ Simple example: port => '9090', fcgi_auth_params => { RULES_URL => 'https://my-server/my.json', + HTTPS_REDIRECT => 'ON', + PORT_REDIRECT => 443 }, # Optional rejection subroutine #on_reject => \&on_reject; @@ -229,6 +240,7 @@ directory. .. code-block:: nginx server { + listen ; server_name "~^(?.+?)\.dev\.sso\.my\.domain$"; location = /lmauth { internal; @@ -243,6 +255,9 @@ directory. fastcgi_param HOST $http_host; # Keep original request (LL::NG server will received /lmauth) fastcgi_param X_ORIGINAL_URI $original_uri; + # Set redirection params + fastcgi_param HTTPS_REDIRECT "$https"; + fastcgi_param PORT_REDIRECT $server_port; } location /rules.json { auth_request off; @@ -261,4 +276,3 @@ directory. } .. |image0| image:: /documentation/devops.png - diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/ApacheMP2/FCGIClient.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/ApacheMP2/FCGIClient.pm index 702f5a010..9c091d02b 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/ApacheMP2/FCGIClient.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/ApacheMP2/FCGIClient.pm @@ -43,7 +43,7 @@ sub handler { SERVER_PORT => $r->get_server_port, REQUEST_METHOD => $r->method, }; - foreach (qw(VHOSTTYPE RULES_URL)) { + foreach (qw(VHOSTTYPE RULES_URL HTTPS_REDIRECT PORT_REDIRECT)) { if ( my $t = $r->dir_config($_) ) { $env->{$_} = $t; } diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/DevOps.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/DevOps.pm index 5fa0943f1..25d6ae506 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/DevOps.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/DevOps.pm @@ -94,6 +94,10 @@ q"I refuse to compile 'rules.json' when useSafeJail isn't activated! Yes I know, $class->locationRulesInit( undef, { $vhost => $json->{rules} } ); $class->headersInit( undef, { $vhost => $json->{headers} } ); $class->tsv->{lastVhostUpdate}->{$vhost} = time; + $class->tsv->{https}->{$vhost} = uc $req->env->{HTTPS_REDIRECT} eq 'ON' + if exists $req->env->{HTTPS_REDIRECT}; + $class->tsv->{port}->{$vhost} = $req->env->{PORT_REDIRECT} + if exists $req->env->{PORT_REDIRECT}; return; } diff --git a/lemonldap-ng-handler/t/64-Lemonldap-NG-Handler-PSGI-DevOps-with-param.t b/lemonldap-ng-handler/t/64-Lemonldap-NG-Handler-PSGI-DevOps-with-param.t index 53f6da7ff..cb1684b3a 100644 --- a/lemonldap-ng-handler/t/64-Lemonldap-NG-Handler-PSGI-DevOps-with-param.t +++ b/lemonldap-ng-handler/t/64-Lemonldap-NG-Handler-PSGI-DevOps-with-param.t @@ -11,9 +11,11 @@ BEGIN { init( 'Lemonldap::NG::Handler::Server', { - #logLevel => 'debug', + #logLevel => 'debug', vhostOptions => { 'test3.example.com' => { + vhostHttps => 0, + vhostPort => 80, vhostDevOpsRulesUrl => 'http://donotuse.example.com/myfile.json', }, @@ -23,6 +25,42 @@ init( my $res; +# Unauthorized queries +ok( + $res = $client->_get( + '/', undef, + 'test3.example.com', undef, + VHOSTTYPE => 'DevOps', + RULES_URL => 'http://devops.example.com/file.json' + ), + 'Unauthorized query' +); +ok( $res->[0] == 302, 'Code is 302' ) or explain( $res->[0], 302 ); +${ $res->[1] }[1] =~ m#http://auth\.example\.com/\?url=(.+?)%#; +ok( decode_base64 $1 eq 'http://test3.example.com/', 'Redirect URL found' ) + or explain( decode_base64 $1, 'http://test3.example.com/' ); +count(3); + +Time::Fake->offset("+700s"); + +ok( + $res = $client->_get( + '/', undef, + 'test3.example.com', undef, + HTTPS_REDIRECT => 'on', + PORT_REDIRECT => 8443, + VHOSTTYPE => 'DevOps', + RULES_URL => 'http://devops.example.com/file.json' + ), + 'Unauthorized query 2' +); +ok( $res->[0] == 302, 'Code is 302' ) or explain( $res->[0], 302 ); +${ $res->[1] }[1] =~ m#http://auth\.example\.com/\?url=(.+?)%#; +ok( decode_base64 $1 eq 'https://test3.example.com:8443/', + 'Redirect URL found' ) + or explain( decode_base64 $1, 'https://test3.example.com:8443/' ); +count(3); + # Authorized queries ok( $res = $client->_get(