Differences

This shows you the differences between two versions of the page.

Link to this comparison view

documentation:2.1:ssoaas [2019/01/15 15:55] (current)
Line 1: Line 1:
 +====== SSO as a service (SSOaaS) ======
  
 +===== Our concept of SSOaaS =====
 +
 +Access management provides 3 services:
 +  * Global Authentication:​ Single Sign-On
 +  * Authorization:​ to grant authentication is not enough. User rights must be checked
 +  * Accounting: SSO logs (access) + application logs //​(transactions and results)//
 +
 +LL::NG affords all these services (except application logs of course, but headers are provided to permit this).
 +
 +Headers setting is an another LL::NG service. LL::NG can provide any user attributes to an application //(see [[writingrulesand_headers|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.
 +
 +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 VM images (Nginx only) includes LL::NG Nginx configuration that aims to a global [[platformsoverview#​external_servers_for_nginx|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 a JSON file, authorization server will read it, apply specified rules and set required headers //(see [[devopshandler|DevOps Handler]])//​.
 +
 +There are two different architectures to do this:
 +  * Using a [[psgi|global FastCGI (or uWSGI) server]]
 +  * Using front reverse-proxies //(some cloud installations use reverse-proxies in front-end)//​
 +
 +In both case, Handler type must be set to [[devopshandler|DevOps]].
 +
 +===== Examples of webserver configuration for Docker/VM images =====
 +
 +==== 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:
 +<file nginx test-nginx.conf>​
 +server {
 +  server_name myapp.domain.com;​
 +  location = /lmauth {
 +    internal;
 +    include /​etc/​nginx/​fastcgi_params;​
 +    # Pass authorization requests to Central FastCGI server:
 +    fastcgi_pass 10.1.2.3:​9090;​
 +    fastcgi_param VHOSTTYPE DevOps;
 +    # Drop post datas
 +    fastcgi_pass_request_body ​ off;
 +    fastcgi_param CONTENT_LENGTH "";​
 +    # Keep original hostname
 +    fastcgi_param HOST $http_host;
 +    # Keep original request (LLNG server will received /lmauth)
 +    fastcgi_param X_ORIGINAL_URI ​ $request_uri;​
 +    ​
 +    # Set dynamically rules (LLNG will poll it every 10 mn)
 +    fastcgi_param RULES_URL http://​rulesserver/​my.json
 +  }
 +  location /rules.json {
 +    auth_request off;
 +    allow 10.1.2.3;
 +    deny all;
 +  }
 +  location ~ ^(.*\.php)$ {
 +    auth_request /lmauth;
 +    auth_request_set $lmremote_user $upstream_http_lm_remote_user;​
 +    auth_request_set $lmlocation $upstream_http_location;​
 +    error_page 401 $lmlocation;​
 +    include /​etc/​lemonldap-ng/​nginx-lua-headers.conf;​
 +    ...
 +    # Example with php-fpm:
 +    include snippets/​fastcgi-php.conf;​
 +    fastcgi_pass unix:/​var/​run/​php/​php7.0-fpm.sock;​
 +  }
 +  location / {
 +    try_files $uri $uri/ =404;
 +  }
 +}
 +</​file>​
 +
 +=== Apache ===
 +
 +There is an experimental FactCGI client in LLNG. You just have to install FCGI::​Client and add this in your apache2.conf:​
 +
 +<file apache apache2.conf>​
 +<​VirtualHost ...>
 +    PerlHeaderParserHandler Lemonldap::​NG::​Handler::​ApacheMP2::​FCGIClient
 +    PerlSetVar LLNG_SERVER 127.0.0.1:​9090
 +    PerlSetVar VHOSTTYPE DevOps
 +    PerlSetVar RULES_URL http://​app.tld/​rules.json
 +    ...
 +</​VirtualHost>​
 +</​file>​
 +
 +=== Node.js ===
 +
 +Using [[https://​github.com/​expressjs/​express#​readme|express]] and [[https://​github.com/​LemonLDAPNG/​node-fastcgi-authz-client|fastcgi-authz-client]],​ you can protect also an Express server. Example:
 +
 +<file javascript app.js>
 +var express = require('​express'​);​
 +var app = express();
 +var FcgiAuthz = require('​fastcgi-authz-client'​);​
 +var handler = FcgiAuthz({
 +  host: '​127.0.0.1',​
 +  port: 9090,
 +  PARAMS: {
 +    RULES_URL: '​http://​my-server/​rules.json'​
 +  }
 +});
 +
 +app.use(handler);​
 +
 +// Simple express application
 +app.get('/',​ function(req,​ res) {
 +  return res.send('​Hello ' + req.upstreamHeaders['​auth-user'​] + ' !');
 +});
 +
 +// Launch server
 +app.listen(3000,​ function() {
 +  return console.log('​Example app listening on port 3000!'​);​
 +});
 +</​file>​
 +
 +=== Plack application ===
 +
 +You just have to enable [[https://​metacpan.org/​pod/​Plack::​Middleware::​Auth::​FCGI|Plack::​Middleware::​Auth::​FCGI]]. Simple example:
 +
 +<file perl app.psgi>​
 +use Plack::​Builder;​
 +
 +my $app   = sub {
 +  my $env = shift;
 +  my $user = $env->​{fcgiauth-auth-user};​
 +  return [ 200, [ '​Content-Type'​ => '​text/​plain'​ ], [ "Hello $user" ] ];
 +};
 +
 +# Optionally ($fcgiResponse is the PSGI response of remote FCGI auth server)
 +#sub on_reject {
 +#    my($self,​$env,​$fcgiResponse) = @_;
 +#    my $statusCode = $fcgiResponse->​{status};​
 +#    ...
 +#}
 +
 +builder
 +{
 +  enable "​Auth::​FCGI",​
 +    host => '​127.0.0.1',​
 +    port => '​9090',​
 +    fcgi_auth_params => {
 +      RULES_URL => '​https://​my-server/​my.json',​
 +    },
 +    # Optional rejection subroutine
 +    #on_reject => \&​on_reject;​
 +    ;
 +  $app;
 +};
 +</​file>​
 +
 +==== Using front reverse-proxies ====
 +
 +This is a simple Nginx configuration file. It looks like a standard 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
 +
 +This configuration handles ''​*.dev.sso.my.domain''​ URL and forwards authenticated requests to ''<​vhost>​.internal.domain''​. Rules can be defined in ''/​rules.json''​ which is located at the website root directory.
 +
 +<file nginx test-nginx.conf>​
 +server {
 +  server_name "​~^(?<​vhost>​.+?​)\.dev\.sso\.my\.domain$";​
 +  location = /lmauth {
 +    internal;
 +    include /​etc/​nginx/​fastcgi_params;​
 +    fastcgi_pass unix:/​home/​xavier/​dev/​lemonldap/​e2e-tests/​conf/​llng-fastcgi.sock;​
 +    # Force handler type:
 +    fastcgi_param VHOSTTYPE DevOps;
 +    # Drop post datas
 +    fastcgi_pass_request_body ​ off;
 +    fastcgi_param CONTENT_LENGTH "";​
 +    # Keep original hostname
 +    fastcgi_param HOST $http_host;
 +    # Keep original request (LLNG server will received /lmauth)
 +    fastcgi_param X_ORIGINAL_URI ​ $request_uri;​
 +  }
 +  location /rules.json {
 +    auth_request off;
 +    allow 127.0.0.0/​8;​
 +    deny all;
 +  }
 +  location / {
 +    auth_request /lmauth;
 +    auth_request_set $lmremote_user $upstream_http_lm_remote_user;​
 +    auth_request_set $lmlocation $upstream_http_location;​
 +    error_page 401 $lmlocation;​
 +    include /​etc/​lemonldap-ng/​nginx-lua-headers.conf;​
 +    proxy_pass https://​$vhost.internal.domain;​
 +  }
 +}
 +</​file>​