Improved security
Date | 2012/08/01 |
Contact(s) | Jesse Eichar, Francois Prunayre |
Last edited | |
Status | Done |
Assigned to release | 2.9.x |
Resources | Funding Ifremer |
Ticket | #1070 |
Code | https://github.com/jesseeichar/core-geonetwork/commits/feature/spring-security |
Overview
This proposal entails the use of Spring Security (http://www.springsource.org/spring-security), a well-known framework that supports the use of one or several security providers. Main goals are:
- SSO configuration (CAS)
- improve LDAP support
- import user privileges (support more than one group, define profile mapping)
- support more than one authentication provider
- when accessing a protected page, user is moved to a login page and will be redirected to the protected resource (instead of ServiceNotAllowed exception #313)
- ... and keep local user database and shibboleth support.
Proposal Type
- Type: Security
- App: GeoNetwork
- Module:
Links
- Email discussions:
- IRC discussions:
- Related work:
Voting History
- None as yet
Proposal
Right now the user-profiles configuration file is used to control what profiles exist and what profiles can access which services. This proposal moves the security control from user-profiles to spring-security.
Example:
<sec:intercept-url pattern="/srv/.*/group.remove(|!).*" access="hasRole('Administrator')"></sec:intercept-url>
Configuration
A set of files config-security* is added in order to easily configure authentication mechanism:
- configure access for GeoNetwork services
- configure authentication provider(s)
- Local database
- LDAP
- LDAP+Local database
- CAS+LDAP
- CAS+local database
The main configuration to activate authentication mechanism is config-security.xml where import could be activated:
<import resource="config-security-core.xml"/> <import resource="config-security-mapping.xml"/> <import resource="config-security-ldap.xml"/> <import resource="config-security-cas.xml"/> <import resource="config-security-cas-ldap.xml"/> <!-- <import resource="config-security-cas-database.xml"/> -->
Then LDAP, CAS configuration (eg. LDAP url, CAS URL, ...) is made in config-security.properties.
LDAP
Connection Settings
To enable LDAP support:
- add the CAS base URL property in config-security.properties::
# LDAP security properties ldap.base.provider.url=ldap://localhost:389 ldap.base.dn=dc=fao,dc=org ldap.security.principal=cn=admin,dc=fao,dc=org ldap.security.credentials=ldap
- ldap.base.provider.url: This tells the portal where the LDAP server is located. Make sure that the computer with the catalog can hit the computer with the LDAP server. Check to make sure that the appropriate ports are opened, etc.
- ldap.base.dn=dc=fao,dc=org: this will usually look something like: "dc=organizationnamehere,dc=org"
- ldap.security.principal & ldap.security.credentials: Define LDAP administrator user to use to bind to LDAP. If not define, an anonymous bind is made. Principal is the username and credentials property the password.
- To verify that you have the correct settings, try to connect to the LDAP server using an LDAP browser application.
- define where to find users in LDAP structure for authentication::
ldap.base.search.base=ou=people ldap.base.dn.pattern=uid={0},${ldap.base.search.base} #ldap.base.dn.pattern=mail={0},${ldap.base.search.base}
- ldap.base.search.base: this is where the catalog will look for users (for authentication)
- ldap.base.dn.pattern: this is the distinguished name for the user to bind with. {0} is replaced by the user name typed in the sign in screen.
- add the following import to config-security.xml::
<import resource="config-security-ldap.xml"/>
Authorization Settings
When using LDAP, user information and privileges could be defined from the LDAP attributes.
User details
All user informations could be retrieved from the LDAP as defined in the config-security-overrides.properties. This property file defined for each user attribute in the catalog database which LDAP attributes match. If the attribute is empty or not defined, a default value could be defined. The configuration is the following::
# Map user information to LDAP attributes and default values # ldapUserContextMapper.mapping[name]=ldap_attribute,default_value ldapUserContextMapper.mapping[name]=cn, ldapUserContextMapper.mapping[surname]=givenName, ldapUserContextMapper.mapping[mail]=mail,data@myorganization.org ldapUserContextMapper.mapping[organisation]=,myorganization ldapUserContextMapper.mapping[kind]=, ldapUserContextMapper.mapping[address]=, ldapUserContextMapper.mapping[zip]=, ldapUserContextMapper.mapping[state]=, ldapUserContextMapper.mapping[city]=, ldapUserContextMapper.mapping[country]=,
Privileges configuration
When using LDAP, user groups and user profiles could be set from LDAP information or not. To manage user privileges from the local database, set the ldap.privilege.import property in config-security.properties to false::
ldap.privilege.import=false
If LDAP information should be used to define user privileges, set it to true::
ldap.privilege.import=true
When importing privileges from LDAP, the catalog administrator could decide to create groups defined in the LDAP and not defined in local database. For this set the following property to true::
ldap.privilege.create.nonexisting.groups=false
======= Simple privileges configuration =======
In order to define which groups the user is member of and which profile is the user::
ldapUserContextMapper.mapping[privilege]=groups,sample # If not set, the default profile is RegisteredUser # Valid profiles are http://geonetwork-opensource.org/manuals/trunk/eng/developer/apidocs/geonetwork/org/fao/geonet/constants/Geonet.Profile.html ldapUserContextMapper.mapping[profile]=privileges,RegisteredUser
Attributes configuration:
- privilege attribute contains the group this user is member of. More than one group is allowed.
- profile attribute contains the profile of the user
======= Profile mapping configuration =======
If LDAP attribute containing profiles does not match the catalog profile list, a mapping could be defined in config-security-overrides.properties::
# Map LDAP custom profiles to catalog profiles. Not used if ldap.privilege.pattern is defined. ldapUserContextMapper.profilMapping[Admin]=Administrator ldapUserContextMapper.profilMapping[Editeur]=Reviewer ldapUserContextMapper.profilMapping[Public]=RegisteredUser
For example, in the previous configuration, the attribute value Admin will be mapped to Administrator (which is a valid profile for the catalog).
======= Advanced privileges configuration =======
An attribute could define both the profile and the group for a user. To extract this information, a custom pattern could be defined to populate user privileges according to that attribute::
# In config-security-overrides.properties ldapUserContextMapper.mapping[privilege]=cat_privileges,sample # In config-security.properties ldap.privilege.pattern=CAT_(.*)_(.*) ldap.privilege.pattern.idx.group=1 ldap.privilege.pattern.idx.profil=2
The LDAP attribute can contains the following configuration to define the different type of users::
-- Define a catalog admin: cat_privileges=CAT_ALL_Administrator -- Define a reviewer for the group GRANULAT cat_privileges=CAT_GRANULAT_Reviewer -- Define a reviewer for the group GRANULAT and editor for MIMEL cat_privileges=CAT_GRANULAT_Reviewer cat_privileges=CAT_MIMEL_Editor -- Define a reviewer for the group GRANULAT and editor for MIMEL and RegisteredUser for NATURA2000 cat_privileges=CAT_GRANULAT_Reviewer cat_privileges=CAT_MIMEL_Reviewer cat_privileges=CAT_NATURA2000_RegisterdUser -- Only a registered user for GRANULAT cat_privileges=CAT_GRANULAT_RegisteredUser
Synchronization
A synchronization task is taking care of removing LDAP user which may be deleted. For example:
- T0: a user A sign in the catalog. A local user A is created in the user database
- T1: A is deleted from the LDAP (A could not sign in in the catalog anymore)
- T2: the synchronization task will check that all local LDAP users exist in LDAP:
- if user is not owner of any records, it will be deleted
- if user is owner of metadata records, warning message is avaialable on the catalog logging system. record's owner should be changed to another user before the task could remove the user.
By default the task is runned once every day. Configuration could be changed in config-security.properties::
# Run LDAP sync every day at 23:30 ldap.sync.cron=0 30 23 * * ?
Debugging
If connection fails, try to increase logging for LDAP in log4j.cfg::
log4j.logger.geonetwork.ldap = DEBUG log4j.logger.org.springframework = DEBUG, console, jeeves log4j.logger.org.springframework.* = DEBUG log4j.logger.org.springframework.security.ldap = DEBUG
CAS
To enable CAS support:
- add the CAS base URL property in config-security.properties::
cas.baseURL=https://localhost:8443/cas cas.ticket.validator.url=${cas.baseURL} cas.login.url=${cas.baseURL}/login cas.logout.url=${cas.baseURL}/logout?url=${geonetwork.https.url}/
- add the following import to config-security.xml::
<import resource="config-security-cas.xml"/> <import resource="config-security-cas-ldap.xml"/>
Backwards Compatibility Issues
- Security configuration is made using configuration file (and not user interface)
- Database changes (migration script provided):
- User table : add a authtype column to identify local/external users
- Configuration overrides would not work at all for that.
Risks
Participants
- As above