On the former security-proxy, there was a mechanism called "SP-trust-SP" which basically allowed to leave the authentication and authorization to another component placed before the security-proxy. The authentication would then be performed by using HTTP headers.
The gateway implements a similar feature, and this can be activated by configuring the gateway using the following:
georchestra:
gateway:
security:
header-authentication:
enabled: true
The following headers are expected to be received by the Gateway:
-
sec-georchestra-preauthenticated
: set totrue
-
preauth-username
: set to the username / user identifier (e.g. "pmauduit") -
preauth-email
: the email address of the user (e.g. "[email protected]") -
preauth-firstname
: the first name of the user (e.g. "Pierre") -
preauth-lastname
: the surname of the user (e.g. "Mauduit") -
preauth-org
: the organisation identifier (e.g. "geOrchestra") -
preauth-provider
: (optional) the external provider (e.g. "myexternalprovider") -
preauth-provider-id
: (optional) the external provider identifier (e.g. "user_123456")
As the framework will consider the received headers as pure us-ascii
, this can lead to issues when values contain
accented characters. To circumvent this, it is possible to
configure the gateway to receive base64-encoded http headers.
If the headers values are prefixed with {base64}
, then the gateway
will
base64-decode the HTTP headers' values - apart from the sec-georchestra-preauthenticated
which should still be set to true
as plaintext - before using them.
In order to be able to administer users who are using the pre-authentication mechanism, an account is created into the geOrchestra OpenLDAP, if available in the gateway configuration.
The account creation must be explicitly activated using the following yaml configuration:
georchestra:
gateway:
security:
header-authentication:
enabled: true
createNonExistingUsersInLDAP: true
To create the user into the geOrchestra LDAP, a default
& extended
LDAP must be
defined, and you generally need read/write access to it, meaning that the adminDn
and adminPassword
have to be provided in the configuration.
Below is a configuration example snippet
suitable for your application.yml
gateway configuration file:
georchestra:
gateway:
security:
header-authentication:
enabled: true
ldap:
default:
enabled: true
extended: true
url: ldap://georchestra-ldap:389/
baseDn: dc=georchestra,dc=org
adminDn: cn=admin,dc=georchestra,dc=org
adminPassword: secret
users:
rdn: ou=users
searchFilter: (uid={0})
pendingUsersSearchBaseDN: ou=pendingusers
protectedUsers: geoserver_privileged_user
roles:
rdn: ou=roles
searchFilter: (member={0})
protectedRoles: ADMINISTRATOR, EXTRACTORAPP, GN_.*, ORGADMIN, REFERENT, USER, SUPERUSER
orgs:
rdn: ou=orgs
orgTypes: Association,Company,NGO,Individual,Other
pendingOrgSearchBaseDN: ou=pendingorgs
As the HTTP headers can be controlled by the remote user issuing the query, it is mandatory to have your gateway inaccessible directly ; on such setup, it must be placed behind another proxy component which will take care of sanitizing the incoming requests.
You can find a documented configuration sample of an Apache webserver which makes use of the mod_mellon
to interact with the Renater federation.
The following Apache configuration has been used in a setup to interact with the Renater federation:
<VirtualHost *:80>
ServerName https://georchestra.example.org:443/
UseCanonicalName On
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Location />
MellonEnable "info"
MellonSecureCookie On
MellonUser eppn
MellonMergeEnvVars On
MellonSubjectConfirmationDataAddressCheck Off
# These have been generated by the mellon_create_metadata script and provided to Renater
MellonSPPrivateKeyFile /etc/apache2/mellon/https_poc_renater.inrae.sandbox.apps.gs_fr_prod.camptocamp.com_.key
MellonSPCertFile /etc/apache2/mellon/https_poc_renater.inrae.sandbox.apps.gs_fr_prod.camptocamp.com_.cert
MellonSPentityId <renater-entity-id>
MellonOrganizationName "ORG"
MellonOrganizationURL "https://example.org"
# This file is downloaded from the Renater Federation, and has to be kept up to date
MellonIdPMetadataFile /etc/apache2/mellon/preview-idps-test-metadata.xml
MellonDiscoveryURL https://discovery.renater.fr/test/WAYF?cru=yes
# These files are also available on the Internet on https://metadata.federation.renater.fr/certs/
MellonIdPCAFile "/etc/apache2/mellon/renater-metadata-signing-cert-2016.pem"
MellonIdPPublicKeyFile "/etc/apache2/mellon/renater-metadata-signing-cert-2016.pem"
MellonProbeDiscoveryTimeout 1
MellonSetEnv "MAIL" "urn:oid:0.9.2342.19200300.100.1.3"
MellonSetEnv "EPPN" "urn:oid:1.3.6.1.4.1.5923.1.1.1.6"
MellonSetEnv "CN" "urn:oid:2.5.4.3"
MellonSetEnv "O" "urn:oid:2.5.4.10"
MellonSetEnv "SN" "urn:oid:2.5.4.4"
MellonSetEnv "GIVEN_NAME" "urn:oid:2.5.4.42"
MellonEndpointPath /mellon
# it is this proxy's responsability to make sure the value of these headers are legit
RequestHeader unset sec-georchestra-preauthenticated
RequestHeader unset preauth-username
RequestHeader unset preauth-email
RequestHeader unset preauth-firstname
RequestHeader unset preauth-lastname
RequestHeader unset preauth-org
RequestHeader unset preauth-provider
RequestHeader unset preauth-provider-id
# The following ones are used by geOrchestra
# You can find a list of headers here:
# https://github.com/georchestra/georchestra/blob/master/commons/src/main/java/org/georchestra/commons/security/SecurityHeaders.java#L41-L67
RequestHeader unset sec-proxy
RequestHeader unset sec-user
RequestHeader unset sec-organization
RequestHeader unset sec-userid
RequestHeader unset sec-lastupdated
RequestHeader unset sec-roles
RequestHeader unset sec-firstname
RequestHeader unset sec-lastname
RequestHeader unset sec-tel
RequestHeader unset sec-orgid
RequestHeader unset sec-orgname
RequestHeader unset sec-org-lastupdated
RequestHeader unset imp-roles
RequestHeader unset imp-username
RequestHeader set sec-georchestra-preauthenticated true "expr=-n env('MELLON_NAME_ID')"
RequestHeader set preauth-username %{MELLON_EPPN}e "expr=-n env('MELLON_EPPN')"
RequestHeader set preauth-email %{MELLON_MAIL}e "expr=-n env('MELLON_MAIL')"
RequestHeader set preauth-firstname %{MELLON_GIVEN_NAME}e "expr=-n env('MELLON_GIVEN_NAME')"
RequestHeader set preauth-lastname %{MELLON_SN}e "expr=-n env('MELLON_SN')"
RequestHeader set preauth-org %{MELLON_O}e "expr=-n env('MELLON_O')"
RequestHeader set preauth-provider myexternalprovider "expr=-n env('MELLON_O')"
RequestHeader set preauth-provider-id %{MELLON_EPPN}e "expr=-n env('MELLON_EPPN')"
# If needed to base64-encode the headers because of them containing accented characters, you can
# use the following syntax and adapt the other headers above:
# RequestHeader set preauth-lastname "expr={base64}%{base64:%{env:MELLON_SN}}" "expr=-n env('MELLON_SN')"
ProxyPass "http://georchestra-gateway-svc:8080/"
ProxyPassReverse "http://georchestra-gateway-svc:8080/"
ProxyPreserveHost On
</Location>
<Location /login/renater>
AuthType Mellon
MellonEnable auth
Require valid-user
Redirect "/"
</Location>
</VirtualHost>
You can see that Apache is taking care of sanitizing the request with the multiple calls to RequestHeader unset
before setting them to a value provided by the mod_mellon
if available, else they are kept unset.
The second Location
allows to trigger an authentication when hitting the /login/renater
endpoint, which is linked onto a custom login page of the gateway.
A docker composition is provided at the root of the repository which integrates a simple Nginx as the frontend proxy. It can be launched using:
$ docker compose -f docker-compose-preauth.yaml up
With the provided datadir/nginx-preauth/nginx.conf
configuration, it should make you logged in as testadmin
without having to login.