Developer’s Corner: Configuring GeoServer to work with Shibboleth and LDAP
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)
Configuring an LDAP based Identity Provider
- 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”
/>
Configuring an Apache Service Provider
-
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>
- Load the so module (in the example we assume an Apache 2.4 is used)
- 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>
GeoServer and Shibboleth
- 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
<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
- 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
Assigning user roles
- 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
- a 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
- a 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
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,