Developer’s Corner: Configuring GeoServer to work with Shibboleth and LDAP

GeoServer

Dear all,
recently we had to integrate GeoServer in a customer security infrastructure.
This infrastructure was using Shibboleth to achieve SSO for a bunch of applications, and GeoServer was part of the game to publish different maps for different users (or better their role(s) in the system).

Shibboleth basics

Shibboleth is a quite complex system, but is able to hide much of the security complexity for the applications behind it.
In short, a Shibboleth security infrastructure is split in two parts:

  • Identity Provider (IdP), that is responsible to authenticate users, receiving SAML requests from Service Providers and answering with a yes/no response and full user data, in case of a positive authentication
  • Service Provider (SP), that allows applications SSO integration through frontend web server configuration (Apache, IIS and others are supported)
Installing and configuring a Shibboleth infrastructure properly can be quite complex, and we won’t explain here all the process.
If you are interested in Shibboleth you can read the related documentation here and here.
What we would like to do in this post  is to give some hints to build a Shibboleth testing platform to test integration with Geoserver if you need to.

Configuring an LDAP based Identity Provider

Standard Identity providers are available to use common source of user data, such as LDAP repositories, databases and so on.
Custom Identity providers can be written to integrate to legacy security infrastructures.
The first thing you will need to do is to install and configure an Identity Provider: you can find the latest Shibboleth Identity Provider package here.
The easiest thing to do is to use an LDAP repository for user storage.
If you install the Windows MSI version, you will get a default configuration using the domain ActiveDirectory service as the user source. This can be good if you want to use your network users for testing. If you don’t, it’s very easy to change the configuration to use a standard OpenLDAP service.
The Identity provider is a web application, with its own Tomcat container, configured to bind to port 443 (https).
After installing it you can test that it’s running correctly connecting to https://localhost/idp/status.
To get a working instance some configuration files will need your intervention. All the configuration files are located in the conf folder of the IdP installation.
Some of them with their usage is:
  • attribute-resolver.xml: this is where the users data source (DataConnector) and attribute extraction rules (AttributeDefinition) are configured ; for example here you can define the connection to your ActiveDirectory or OpenLDAP repository and which attributes are to bound to users; some configuration snippets to configure an LDAP DataConnector and a new attribute on it is:

<resolver:DataConnector id=”myLDAP” xsi:type=”LDAPDirectory” xmlns=”urn:mace:shibboleth:2.0:resolver:dc”
useStartTLS=”false”
ldapURL=”ldap://localhost:389” baseDN=”OU=People,DC=maxcrc,DC=com” principal=”cn=Manager,dc=maxcrc,dc=com
principalCredential=”secret“>

<FilterTemplate>
<![CDATA[
(uid=$requestContext.principalName)
]]>
</FilterTemplate>

<LDAPProperty name=”java.naming.referral” value=”follow”/>

</resolver:DataConnector>

<resolver:AttributeDefinition xsi:type=”ad:Simple” id=”description” sourceAttributeID=”description“>

<resolver:Dependency ref=”myLDAP” />
<resolver:AttributeEncoder xsi:type=”enc:SAML1String” name=”urn:mace:dir:attribute-def:description” />
<resolver:AttributeEncoder xsi:type=”enc:SAML2String” name=”urn:oid:2.5.4.13″ friendlyName=”description” />

</resolver:AttributeDefinition>

  • login.config: this is a JAAS configuration for the login module; here you must repeat the LDAP repository connection settings. Here an example:

ShibUserPassAuth {

edu.vt.middleware.ldap.jaas.LdapLoginModule required

host=”localhost”
port=”389″
base=”ou=People,dc=maxcrc,dc=com”
tls=”false”
serviceCredential=”secret”
userRoleAttribute=”uid”
serviceUser=”cn=Manager,dc=maxcrc,dc=com”
subtreeSearch = “true”
userField=”uid”;

};

  • attribute-filter.xml: here the attribute visibility (by user) can  be configured; if you add new attributes in attribute-resolver.xml, remember to give access to them through this file adding an AttributeRule, for example  to allow access to the description attribute to anyone:

<afp:AttributeRule attributeID=”description“>

<afp:PermitValueRule xsi:type=”basic:ANY” />

</afp:AttributeRule>

  • relying-party.xml: here connection to service provider(s) is defined: be sure to have a MetadataProvider for each ServiceProvider you have to serve (usually just one for test purposes); basically you need to add something similar to the following to the ChainingMetadataProvider section:

<metadata:MetadataProvider id=”<SpHost>” xsi:type=”metadata:FileBackedHTTPMetadataProvider”
metadataURL=”http://<SpHost>/Shibboleth.sso/Metadata
backingFile=”<IdPInstallPath>/metadata/<sphost>.xml
/>

Remember to restart the IdP Tomcat instance every time a configuration change is done and use logs in the IdP logs folder to check any problem you can have.

Configuring an Apache Service Provider

The Service Provider is the Shibboleth component directly integrated with the applications to be secured.
While the IdP is usally only one in the entire infrastructure (as we need to implement Single Sign On), we can have a Service Provider for each application or set of applications that use a common frontend.
The first thing you need to do is to install the required Service Provider. The latest download can be found here.
Installing the SP, a daemon (or service) will be created. This will communicate with Apache through an apache so module (to be configured in Apache itself).
To successfully connect the SP to the IdP some configuration files would need your intervention. All the configuration files are located in the etc/shibbolet folder of the SP installation.
Some of them with their usage is:
  • Shibboleth2.xml: here you should configure the ApplicationDefaults section, to decide the security scheme for secured applications and connect to the IdP:

<ApplicationDefaults entityID=”https://<SpHost>/shibboleth

REMOTE_USER=”displayName

signing=”false” encryption=”false”

attributePrefix=”AJP_“>

<SSO entityID=”https://<IdP>/idp/shibboleth
discoveryProtocol=”SAMLDS” discoveryURL=”https://ds.example.org/DS/WAYF”>
SAML2 SAML1
</SSO>

</ApplicationDefaults>

<MetadataProvider type=”XML” file=”<IdPPath>/metadata/idp-metadata.xml“/>

  • attribute-map.xml: define Attribute you need to be seen by applications (matching those defined for the IdP, for example LDAP attributes):

<Attribute name=”urn:mace:dir:attribute-def:displayName” id=”ShibbolethUser“/>

  • attribute-policy.xml:  to configure visibility policies for specific attributes, for example to make all attributes visible, you can use:

<afp:AttributeRule attributeID=”*“>
<afp:PermitValueRule xsi:type=”ANY“/>
</afp:AttributeRule>

Remember to restart the SP service every time a configuration change is done and use logs in the SP var/log/shibboleth folder to check any problem you can have.
To enable Shibboleth on Apache some configuration is needed too (in the usual Apache configuration file(s)):
  • Load the so module (in the example we assume an Apache 2.4 is used)
LoadModule mod_shib <ShibbolethSPPath>/lib/shibboleth/mod_shib_24.so
  • Configure the SSO handler location:

<Location /Shibboleth.sso>

 AuthType None

 Require all granted

</Location>

  • Secure specific locations:

<Location /secure>

AuthType shibboleth

ShibRequestSetting requireSession 1

ShibUseHeaders On

require valid-user

</Location>

If your application is a Java webapp proxied by AJP to Apache, you also need to add some properties to the AJP connector in the web container configuration. For example, if using Tomcat you should use the following:
<Connector port=”8009″ protocol=”AJP/1.3″ tomcatAuthentication=”false” scheme=”https” redirectPort=”443″ address=”127.0.0.1″/>

GeoServer and Shibboleth

To use GeoServer inside a Shibboleth infrastructure a best practice is:
  • use an Apache instance as frontend, and configure the shibboleth module to secure the geoserver locations
  • connect Apache and the Geoserver Tomcat instance through AJP
An example of configuration for the geoserver secured location in Apache is:

<Location /geoserver>
AuthType shibboleth
ShibRequestSetting requireSession 1
ShibUseHeaders On
require valid-user
</Location>
This way, every access to the GeoServer UI and services is automatically authenticated by the SSO infrastructure. For example:

  • any unauthenticated request is redirected to the authentication app (part of the Identity Provider)
  • any SSO authenticated request is automatically recognized and user data is forwarded to the called application
From the GeoServer point of view, what we need to do is:
  • recognize Shibboleth user data and use it to automatically authenticate the user requests
  • assign the correct roles to user to enforce access rules

Authenticating Shibboleth users

For the first task you need to know that Shibboleth is able to forward user data to applications using two distinct methods:

  • adding headers to the request
  • setting cgi-variables
The first one is less secure, but it can be implemented without any extra code, because GeoServer already supports an “HTTP Header Authentication Filter”. Simply configure it to use the Shibboleth “username” header to authenticate the user. The name of the header is not fixed, it depends on Shibboleth configuration (for example it can be mapped to a specific property of the user in the LDAP repository). In the Service Provider configuration example we configured it to ShibbolethUser, so the header will be named AJP_ShibbolethUser (we also configured the AJP prefix for all the headers forwarded via AJP).
To implement authentication via cgi-variables a new filter needs to be implemented, but this is quite simple and similar to the HTTP Header one. We may implement it in a near future, if needed.

Assigning user roles

To assign roles to users, the HTTP Header Authentication Filter allows to use several sources:
  • another HTTP header: in many configurations, roles information is saved in the same repository of other user data (such as LDAP), so Shibboleth can be easily instructed to include them in forwarded user data
  • GeoServer UserGroupService: this is the most tedious option, because roles need to be configured inside GeoServer, use it as the last choice if you don’t have any other solution
  • GeoServer RoleService: if, for example, Shibboleth doesn’t give you roles information, you can use the LDAPRoleService to fetch them directly from the LDAP repository
For our customer, neither of the above options was available, since roles could be fetched only querying a custom web service: for this reason we implemented a custom RoleService for him.
This shows how flexible the GeoServer security subsystem is, thanks to the underlying Spring Security Framework.

If you are interested in learning about how we can help you achieving your goals with our Open Source products and professional services, do not hesitate to contact us!

The GeoSolutions team,