diff --git a/doc/sources/admin/handlerauthbasic.rst b/doc/sources/admin/authbasichandler.rst similarity index 100% rename from doc/sources/admin/handlerauthbasic.rst rename to doc/sources/admin/authbasichandler.rst diff --git a/doc/sources/admin/authchoice.rst b/doc/sources/admin/authchoice.rst index e45ff951a..a9936d778 100644 --- a/doc/sources/admin/authchoice.rst +++ b/doc/sources/admin/authchoice.rst @@ -51,7 +51,7 @@ Then, go in ``Choice Parameters``: ``lmAuth``) - **Allowed modules**: click on ``New chain`` to add a choice. - **Choice used for password authentication**: authentication module used by - :doc:`AuthBasic handler` and :ref:`OAuth2.0 Password Grant ` + :doc:`AuthBasic handler` and :ref:`OAuth2.0 Password Grant ` - **FindUser plugin parameter**: authentication module called by Find user plugin (:doc:`Find user plugin`) diff --git a/doc/sources/admin/configvhost.rst b/doc/sources/admin/configvhost.rst index 9ff7c3e15..e6b4707db 100644 --- a/doc/sources/admin/configvhost.rst +++ b/doc/sources/admin/configvhost.rst @@ -38,7 +38,7 @@ Example of a protected virtual host for a local application: -Reverse proxy +Reverse-Proxy ~~~~~~~~~~~~~ Example of a protected virtual host with LemonLDAP::NG as reverse proxy: @@ -258,7 +258,7 @@ Example of a protected virtual host for a local application: .. _reverse-proxy-1: -Reverse proxy +Reverse-Proxy ~~~~~~~~~~~~~ - Example of a protected reverse-proxy: @@ -452,7 +452,7 @@ A virtual host contains: - Access rules: check user's right on URL patterns - HTTP headers: forge information sent to protected applications - POST data: use form replay -- Options: redirection port and protocol +- Options: redirection port, protocol, Handler type, aliases,required authentication level,... Access rules and HTTP headers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -464,7 +464,7 @@ application by LL::NG. .. attention:: - With **Nginx**-based ReverseProxy, header directives can + With **Nginx**-based Reverse-Proxy, header directives can be appended by a LUA script. To send more than **15** headers to protected applications, @@ -507,9 +507,12 @@ Some options are available: Provide a comma separated parameters list with custom function path and args. Args can be vars or session attributes, macros, ... By example: My::accessToTrace, Doctor, Who, _whatToTrace -- **Type**: handler type (normal, - :doc:`ServiceToken Handler`, - :doc:`DevOps Handler`,...) +- **Type**: handler type (:ref:`Main`, + :doc:`AuthBasic`, + :doc:`ServiceToken`, + :doc:`DevOps`, + :doc:`DevOpsST`, + :doc:`OAuth2`,...) - **Required authentication level**: this option avoids to reject user with a rule based on ``$_authenticationLevel``. When user has not got the required level, he is redirected to an upgrade page in the portal. diff --git a/doc/sources/admin/devopshandler.rst b/doc/sources/admin/devopshandler.rst index d06b29427..5fe8fd2bf 100644 --- a/doc/sources/admin/devopshandler.rst +++ b/doc/sources/admin/devopshandler.rst @@ -1,7 +1,7 @@ DevOps Handler ============== -This Handler is designed to retrieve vhost configuration from the website +This Handler is designed to retrieve VHost configuration from the website itself, not from LL:NG configuration. Rules and headers are set in a **rules.json** file stored at the website root directory (ie ``http://website/rules.json``). This file looks like: @@ -23,12 +23,14 @@ If this file is not found, the default rule "accept" is applied and just No specific configuration is required except that: -- you have to choose this specific handler (directly by using - ``VHOSTTYPE`` environment variable or in VHost options) -- you can set the loopback URL needed by the DevOps handler to get - ``/rules.json`` or use ``RULES_URL`` parameter to set JSON file path - (see :doc:`SSO as a Service`). Default to - ``http://127.0.0.1:`` +- you have to select ``DevOps`` handler type either with + ``VHOSTTYPE`` environment variable or in VHost options +- you can set in VHost options the loopback URL requested by + the DevOps handler to retrieve ``/rules.json`` or use + ``RULES_URL`` environment variable to set JSON file location. + Default to ``http://127.0.0.1:`` +- HTTPS or redirection port can be set by using + ``HTTP_REDIRECT`` or ``PORT_REDIRECT`` environment variables. .. attention:: diff --git a/doc/sources/admin/handlerarch.rst b/doc/sources/admin/handlerarch.rst index bdf5c181f..71962e24b 100644 --- a/doc/sources/admin/handlerarch.rst +++ b/doc/sources/admin/handlerarch.rst @@ -25,7 +25,7 @@ Plack servers protection or Nginx/\ :doc:`SSOaaS` FastCGI/uWSGI server S Types are: - *(Main)*: link between Main and platform -- :doc:`AuthBasic` +- :doc:`AuthBasic` - :doc:`CDA` - :doc:`DevOps` - :doc:`DevOps+ServiceToken` diff --git a/doc/sources/admin/index_advanced.rst b/doc/sources/admin/index_advanced.rst index 5f4edb91f..86eb000c0 100644 --- a/doc/sources/admin/index_advanced.rst +++ b/doc/sources/admin/index_advanced.rst @@ -18,7 +18,7 @@ Advanced features register logoutforward securetoken - handlerauthbasic + authbasichandler safejail loginhistory fastcgi diff --git a/doc/sources/admin/index_handler.rst b/doc/sources/admin/index_handler.rst index 9530914b8..932544026 100644 --- a/doc/sources/admin/index_handler.rst +++ b/doc/sources/admin/index_handler.rst @@ -4,7 +4,7 @@ Handlers .. toctree:: :maxdepth: 1 - handlerauthbasic + authbasichandler cda ssoaas oauth2handler diff --git a/doc/sources/admin/psgi.rst b/doc/sources/admin/psgi.rst index 4a31e242d..db8927653 100644 --- a/doc/sources/admin/psgi.rst +++ b/doc/sources/admin/psgi.rst @@ -1,7 +1,7 @@ Advanced PSGI usage =================== -LLNG is build on `Plack `__, so it can be used +LL::NG is built on `Plack `__, so it can be used with any compatible server: - `Starman `__ @@ -46,19 +46,18 @@ to replace exactly FastCGI server. You can use it : .. attention:: - Starman, Twiggy,... are HTTP servers, not FastCGI ones - ! + Starman, Twiggy,... are HTTP servers, not FastCGI ones! You can also replace only a part of it to create a specialized FastCGI server (portal,...). Look at ``llng-server.psgi`` example and take the part you want to use. -There are also some other psgi files in examples directory. +There are also some other PSGI files in examples directory. -LLNG FastCGI Server -~~~~~~~~~~~~~~~~~~~ +LL::NG FastCGI Server +~~~~~~~~~~~~~~~~~~~~~ -``llng-fastcgi-server`` can be launched with the following options: +``llng-fastcgi-server`` can be started with the following options: ==================== ===================== ===================== ========================================================================================== Command-line options Environment variable Explanation @@ -98,16 +97,15 @@ FCGI::Engine::ProcManager Using uWSGI ~~~~~~~~~~~ -You must install uWSGI PSGI plugin. Then for example, launch +You have to install uWSGI PSGI plugin. Then for example, start llng-server.psgi *(simple example)*: -:: +.. code-block:: shell /usr/bin/uwsgi --plugins psgi --socket :5000 --uid www-data --gid www-data --psgi /usr/share/lemonldap-ng/llng-server/llng-server.psgi -You will find in LLNG Nginx configuration files some comments that -explain how to configure Nginx to use uWSGI instead of LLNG FastCGI -server. +You will find in LL::NG Nginx configuration files some comments that +explain how to configure Nginx to use uWSGI instead of LL::NG FastCGI server. Using Debian lemonldap-ng-uwsgi-app package ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +146,7 @@ and/or Nginx init files several options. Example: .. note:: Nginx natively includes support for upstream servers speaking the uwsgi protocol since version 0.8.40. - To improve performances, you can switch from a TCP socket to an Unix Domain Socket by editing + To improve performances, you can switch from a TCP socket to an UDS socket by editing ``llng-server.yaml``: .. code-block:: ini @@ -161,7 +159,7 @@ and/or Nginx init files several options. Example: .. code-block:: nginx - # OR TO USE uWSGI + # With uWSGI include /etc/nginx/uwsgi_params; uwsgi_pass unix:///tmp/uwsgi.sock; uwsgi_param LLTYPE psgi; @@ -174,8 +172,8 @@ and/or Nginx init files several options. Example: Protect a PSGI application -------------------------- -LLNG provides ``Plack::Middleware::Auth::LemonldapNG`` that can be used -to protect any PSGI application: it acts exactly like a LLNG handler. +LL::NG provides ``Plack::Middleware::Auth::LemonldapNG`` that can be used +to protect any PSGI application: it works exactly like a LL::NG handler. Simple example: .. code-block:: perl diff --git a/doc/sources/admin/ssoaas.rst b/doc/sources/admin/ssoaas.rst index b079a4870..eb81af4db 100644 --- a/doc/sources/admin/ssoaas.rst +++ b/doc/sources/admin/ssoaas.rst @@ -1,4 +1,4 @@ -SSO as a service (SSOaaS) +SSO as a Service (SSOaaS) ========================= Our concept of SSOaaS @@ -13,45 +13,46 @@ Access management provides 3 services: results)* LL::NG affords all these services (except application logs of course, -but headers are provided to permit this). +but headers are provided to allow this). Headers setting is an another LL::NG service. LL::NG can provide any -user attributes to an application (see -:doc:`Rules and headers`) +user attributes to an application +(see :doc:`Rules and headers`) ``*aaS`` means that application can drive underlying layer (IaaS for infrastructure, PaaS for platform,…). So for us, ``SSOaaS`` must provide -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. +the ability for an application to manage authorizations and choose user +attributes to set. Authentication can not be really ``*aaS``: application +must just use it but not manage it. 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 defines a RULES_URL parameter that refers to +service. So a web application can manage its rules and headers. +Docker or VM images (Nginx only) includes LL::NG Nginx configuration that +aims to a +:ref:`central LL::NG authorization server`. +By default, all authenticated users can access and just one header is set: +``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`). -There are two different architectures to do this: +Two different kind of architecture are existing to do this: -- Using a :doc:`global FastCGI (or uWSGI) server` -- Using front reverse-proxies *(some cloud installations use +- Using a :doc:`central FastCGI (or uWSGI) server` +- Using front Reverse-Proxies *(some cloud or HA installations use reverse-proxies in front-end)* .. note:: - Some requests can be dropped by the FastCGI/uWSGI server. - Example below with uWSGI server to avoid Load Balancer health check requests - being forwarded to DevOps Handler: + Some requests can be dropped by the central FastCGI/uWSGI server. + + Example below with an uWSGI server to prevent Load Balancer health check requests + being forwarded to the central DevOps Handler: ```route-remote-addr = ^127\.0\.0\.25[34]$ break: 403 Forbidden for IP ${REMOTE_ADDR}``` -Example of a global FastCGI architecture: +Example of a central FastCGI architecture: |image0| @@ -60,17 +61,17 @@ In both case, Handler type must be set to :doc:`DevOps`. Examples of webserver configuration for Docker/VM images -------------------------------------------------------- -Using a global FastCGI (or uWSGI) server -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Using a Central FastCGI (or uWSGI) Server +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nginx ^^^^^ -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): +Examples below are web server templates customized for +requesting authorization from a central FastCGI server. +With a central uWSGI server (Nginx only), use 'uwsgi_param' directive: -.. code:: +.. code-block:: nginx server { listen ; @@ -78,7 +79,7 @@ With an uWSGI central server, use 'uwsgi_param' directive (Nginx only): location = /lmauth { internal; include /etc/nginx/fastcgi_params; - # Pass authorization requests to Central FastCGI server: + # Pass authorization requests to central FastCGI server fastcgi_pass 10.1.2.3:9090; fastcgi_param VHOSTTYPE DevOps; # Drop post datas @@ -89,11 +90,11 @@ With an uWSGI central server, use 'uwsgi_param' directive (Nginx only): # Keep original request (LLNG server will received /lmauth) fastcgi_param X_ORIGINAL_URI $original_uri; - # Set redirection params + # Set redirection parameters fastcgi_param HTTPS_REDIRECT "$https"; fastcgi_param PORT_REDIRECT $server_port; - # Set dynamically rules (LL::NG will poll it every 10 mn) + # Set rules dynamically (LL::NG will poll it every 10 mn) fastcgi_param RULES_URL http://rulesserver/my.json; } location /rules.json { @@ -109,7 +110,7 @@ With an uWSGI central server, use 'uwsgi_param' directive (Nginx only): error_page 401 $lmlocation; include /etc/nginx/nginx-lua-headers.conf; # ... - # Example with php-fpm: + # Example with php-fpm include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; } @@ -121,12 +122,12 @@ With an uWSGI central server, use 'uwsgi_param' directive (Nginx only): Apache ^^^^^^ -There is an experimental FastCGI client in LL::NG. You just have to -install LemonLDAP::NG handler and FCGI::Client. Then, add this in -your apache2.conf, web applications or reverse-proxies. +LL::NG provides an experimental FastCGI client. You have to +install LemonLDAP::NG handler (LL::NG FastCGI client), +FCGI::Client (Perl dependency) and Mod_Perl2 (Apache module) +used for parsing HTTP headers. +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 @@ -134,7 +135,7 @@ FastCGI" configuration. ServerName app.tls PerlHeaderParserHandler Lemonldap::NG::Handler::ApacheMP2::FCGIClient - # This must point to the central FastCGI server + # The central FastCGI server socket PerlSetVar LLNG_SERVER 192.0.2.1:9090 # Declare this vhost as a DevOps protected vhost. So you do not have @@ -224,15 +225,15 @@ Simple example: $app; }; -Using front reverse-proxies +Using front Reverse-Proxies ~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is a simple Nginx configuration file. It looks like a standard -LL::NG nginx configuration file except for: +LL::NG Nginx configuration file except for: - VHOSTTYPE parameter forced to use DevOps handler -- /rules.json must not be protected by LL::NG but by the web server - itself +- /rules.json do not have to be protected by LL::NG + but by the web server itself. This configuration handles ``*.dev.sso.my.domain`` URL and forwards authenticated requests to ``.internal.domain``. Rules can be diff --git a/doc/sources/admin/start.rst b/doc/sources/admin/start.rst index 569c890e1..a959665f8 100644 --- a/doc/sources/admin/start.rst +++ b/doc/sources/admin/start.rst @@ -315,7 +315,7 @@ Handlers are software control agents to be installed on your web servers Handler type Apache LLNG FastCGI/uWSGI server (Nginx, or :doc:`SSOaaS`) `Plack servers `__ Node.js ( `express apps `__\ or :doc:`SSOaaS`) :doc:`Self protected apps` Comment ==================================================================== ========== ============================================================= =========================================== ================================================================================== =============================================== ====================================================================================================================== Main *(default handler)* ✔ ✔ ✔ :doc:`Partial` ** [16]_ ** ✔ -:doc:`AuthBasic` ✔ ✔ ✔ ✔ Designed for some server-to-server applications +:doc:`AuthBasic` ✔ ✔ ✔ ✔ Designed for some server-to-server applications :doc:`CDA` ✔ ✔ ✔ ✔ For Cross Domain Authentication :doc:`DevOps` (:doc:`SSOaaS`) |new| ✔ ✔ ✔ ✔ Allows application developers to define their own rules and headers inside their applications :doc:`DevOpsST` (:doc:`SSOaaS`) |new| ✔ ✔ ✔ ✔ Enables both :doc:`DevOps` and :doc:`Service Token` @@ -464,7 +464,7 @@ Advanced features - :doc:`Create an account (self service)` - :doc:`Forward logout to applications` - :doc:`Secure Token Handler` -- :doc:`AuthBasic Handler` +- :doc:`AuthBasic Handler` - :doc:`SSO as a Service` *(SSOaaS)* |new| - :doc:`Handling server webservice calls` |new| - `LemonLDAP::NG kubernetes diff --git a/doc/sources/admin/upgrade_2_0.rst b/doc/sources/admin/upgrade_2_0.rst index bcbb658f5..a02a272e7 100644 --- a/doc/sources/admin/upgrade_2_0.rst +++ b/doc/sources/admin/upgrade_2_0.rst @@ -170,7 +170,7 @@ Handlers - :doc:`CDA`, :doc:`ZimbraPreAuth`, :doc:`SecureToken` and - :doc:`AuthBasic` are now + :doc:`AuthBasic` are now :doc:`Handler Types`. So there is no more special file to load: you just have to choose "VirtualHost type" in the manager/VirtualHosts. @@ -222,7 +222,7 @@ SOAP/REST services .. attention:: - \ :doc:`AuthBasic Handler` uses now + \ :doc:`AuthBasic Handler` uses now REST services instead of SOAP. CAS diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/Status.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/Status.pm index 842be9cda..941ec5bd9 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/Status.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/Status.pm @@ -63,7 +63,7 @@ sub run { # Activity collect if ( -/^(\S+)\s+=>\s+(\S+)\s+(OK|REJECT|REDIRECT|LOGOUT|UNPROTECT|\-?\d+)$/ +/^(\S+)\s+=>\s+(\S+)\s+(OK|REJECT|REDIRECT|LOGOUT|UNPROTECT|SKIP|EXPIRED|\-?\d+)$/ ) { my ( $user, $uri, $code ) = ( $1, $2, $3 ); diff --git a/lemonldap-ng-portal/MANIFEST b/lemonldap-ng-portal/MANIFEST index d2576a554..ddbaaaedb 100644 --- a/lemonldap-ng-portal/MANIFEST +++ b/lemonldap-ng-portal/MANIFEST @@ -512,6 +512,7 @@ t/20-Auth-and-password-DBI.t t/20-Auth-DBI-utf8.t t/21-Auth-and-password-LDAP.t t/21-Auth-LDAP-attributes.t +t/21-Auth-LDAP-Policy-Combination.t t/21-Auth-LDAP-Policy-only.t t/21-Auth-LDAP-Policy.t t/22-Auth-and-password-AD.t diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Process.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Process.pm index 587d00de2..3a01d6bd9 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Process.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Process.pm @@ -505,6 +505,8 @@ sub setPersistentSessionInfo { sub setLocalGroups { my ( $self, $req ) = @_; + $req->{sessionInfo}->{groups} //= ''; + $req->{sessionInfo}->{hGroups} //= {}; foreach ( sort keys %{ $self->_groups } ) { if ( $self->_groups->{$_}->( $req, $req->sessionInfo ) ) { $req->{sessionInfo}->{groups} .= diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm index 0d4a072ea..38b8fab6f 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm @@ -134,7 +134,7 @@ sub login { return $self->do( $req, [ - 'checkUnauthLogout', 'controlUrl', # Fix 2342 + 'checkUnauthLogout', 'controlUrl', # Fix 2342 @{ $self->beforeAuth }, $self->authProcess, @{ $self->betweenAuthAndData }, $self->sessionData, @{ $self->afterData }, $self->validSession, @@ -148,7 +148,7 @@ sub postLogin { return $self->do( $req, [ - 'checkUnauthLogout', 'restoreArgs', # Fix 2342 + 'checkUnauthLogout', 'restoreArgs', # Fix 2342 'controlUrl', @{ $self->beforeAuth }, $self->authProcess, @{ $self->betweenAuthAndData }, $self->sessionData, @{ $self->afterData }, @@ -189,7 +189,8 @@ sub refresh { $req->user( $data{_user} || $data{ $self->conf->{whatToTrace} } ); $req->id( $data{_session_id} ); foreach ( keys %data ) { - delete $data{$_} unless ( /^_/ or /^(?:startTime|authenticationLevel)$/ ); + delete $data{$_} + unless ( /^_/ or /^(?:startTime|authenticationLevel)$/ ); } $data{_updateTime} = strftime( "%Y%m%d%H%M%S", localtime() ); $self->logger->debug( @@ -356,6 +357,11 @@ sub do { sub getModule { my ( $self, $req, $type ) = @_; + if ( my $val = + $req->userData->{ { auth => '_auth', user => '_userDB' }->{$type} } ) + { + return $val; + } if ( my $mod = { auth => '_authentication', diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/LDAP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/LDAP.pm index 69530415a..b01edb904 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/LDAP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/LDAP.pm @@ -58,8 +58,8 @@ sub setSessionInfo { # @return Lemonldap::NG::Portal constant sub setGroups { my ( $self, $req ) = @_; - my $groups = $req->{sessionInfo}->{groups}; - my $hGroups = $req->{sessionInfo}->{hGroups}; + my $groups = $req->{sessionInfo}->{groups} || ''; + my $hGroups = $req->{sessionInfo}->{hGroups} || {}; if ( $self->conf->{ldapGroupBase} ) { diff --git a/lemonldap-ng-portal/t/01-Unauth-Logout.t b/lemonldap-ng-portal/t/01-Unauth-Logout.t index 52b429e31..d1e56bf20 100644 --- a/lemonldap-ng-portal/t/01-Unauth-Logout.t +++ b/lemonldap-ng-portal/t/01-Unauth-Logout.t @@ -5,7 +5,7 @@ require 't/test-lib.pm'; my $res; my $client = LLNG::Manager::Test->new( - { ini => { logLevel => 'debug', useSafeJail => 1 } } ); + { ini => { logLevel => 'error', useSafeJail => 1 } } ); # Test unauthenticated logout request with param ok(