Table of Contents

SSO as a service (SSOaaS)

Our concept of SSOaaS

Access management provides 3 services:

LLNG provides all these services (except application logs of course, but headers are provided to permit this). Headers is another LLNG service: LLNG can provide any user attributes to the application (see Rules and headers)

*aaS means that application can drive undelying layer (IaaS for infrastructure, PaaS for platform,…). So for us, SSOaaS must provide the ability for an app to manage authorizations and to get user attributes. Authentication can't be really “*aaS”: app must not drive it, only consumes it.

LLNG provides some features that can be used to provide SSO as a service: a web application can drive its rules and headers. Docker or VM images (Nginx only) includes LLNG Nginx configuration that points to a global LLNG authorization server. By default, all authenticated users can access and one header is set: Auth-User. If application gives a RULES_URL parameter that points to a JSON file, authorization server will read it and apply given rules and set asked headers (see DevOps Handler).

Two architectures to do it:

In both case, Handler type must be set to DevOps.

Using front reverse-proxies

Here is a simple Nginx configuration file. It looks like a standard LLNG nginx configuration file except that:

This configuration handles *.dev.sso.my.domain services and forward authenticated requests to <vhost>.internal.domain. Rules can be defined in the root of the website in the file /rules.json.

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;
  }
}

Using a global FastCGI (or uWSGI) server

In this example, web server templates (Nginx only) are configured to ask authorization to a central FastCGI server

test-nginx.conf
server {
  server_name myapp.domain.com;
  location = /lmauth {
    internal;
    include /etc/nginx/fastcgi_params;
    # 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 /llauth)
    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;
  }
}