wiki:ServiceProviderFederation/CLARIN IdP

1. Current policies

1.1. Account activation workflow

  • Is this account request clearly a spammer? Delete account and indicate it is Spam to the mollom plugin. Else:
    • Did the user indicate in the personal expertise field that (s)he is a developer? Then enable the developer role and activate account. Else:
      • Is the user affiliated to an organisation that occurs in the Discovery service?
        • If so, send request to use own Identity Provider. After two weeks without reaction, delete account; do not indicate anything to the mollom plugin.
        • If not, check if the account is academic.
          • If so, activate account + enable academic role.
          • If not, send request for motivation.
            • If the request is well-motivated, activate account. Do not set the role academic.
            • If the request is not well-motivated, defer and inform the user. Do not indicate anything to the mollom plugin.
            • If the user does not reply within two weeks, delete account, informing the user and indicate it is low quality to the mollom plugin.

2. New CLARIN IdP (2016-)

We want to replace the current CLARIN IdP and https://user.clarin.eu administration frontend with a Unity IDM based setup.

2.1. Requirements

Some functional requirements formulated by Dieter:

  1. SAML 2 Idp, CLARIN-approvoved certificate
  2. IdP delivers the following attributes: eduPersonPrincipalName, mail, cn, o (fixed value CLARIN), schacHomeOrganizaton (fixed value clarin.eu)
  3. An administrator group can (dis)approve account requests
  4. administer the IdP via a GUI (https) with support for the following workflow:
    1. user requests account; CAPTCHA required
    2. user adds information: name, address,…, motivation
    3. User clicks on link in verification mail
    4. IdP administrators get a mail with all info for the approval
    5. Administrators can remove, import and export accounts
  5. Users need to be able to change their account without involvement of the administrator (although this should be logged)
  6. User can request a new password and can change their existing password
  7. Blacklist certain mail domains
  8. Inform the users that the use of an existing institutional IdP is preferred. Give a link to test if their home organization has an IdP
  9. Export and import user accounts as CSV with the passwords as an MD5 hash without a salt (for the compatibility with the current clarin.eu IdP)

2.1.1. Documents

Use case, first exploration of options: Status report about the new Identity/Access Infrastructure for CLARIN

Detailed information about requirements: Implementation plan

Early draft of a test plan: Test plan

2.2. Technical info

2.2.1. DNS subdomains of clarin.eu

dev-user: Jozef's development server, with Unity IDM with LDAP connector.

user: CLARIN LDAP (OpenDJ) and IAM server (currently Drupal 6, later Unity IDM)

test-idp: ?

dev-idp: current testing instance of Unity IDM

idp: current CLARIN IdP (Shibboleth)

2.3. Groups (current)

ou=groups,dc=clarin,dc=eu
cn=everyone,ou=groups,dc=clarin,dc=eu
cn=administrator,ou=groups,dc=clarin,dc=eu
cn=academic,ou=groups,dc=clarin,dc=eu
cn=board,ou=groups,dc=clarin,dc=eu
cn=webform,ou=groups,dc=clarin,dc=eu
cn=developer,ou=groups,dc=clarin,dc=eu

3. Implementation

3.1. Unity IDM LDAP endpoint

3.1.1. What do we want?

We want an LDAP endpoint implemented in UNITY so LDAP clients can query UNITY and get user information. We will *not* implement a 1:1 mapping between LDAP query language and UNITY backend but implement the minimal requirements in order to support LDAP plugin for Drupal and apache integration.

3.1.2. What do we want in more detail?

We want an LDAP server listening on a port (note that LDAP is not based on http). Because Unity is based on Jetty and servlet containers are in general unfriendly to non http protocols, an embedded LDAP server is used that listens on a different port than Unity. Moreover, there are only a few +- working LDAP servers so the choice was easy - Apache DS (https://directory.apache.org/studio/). Furthermore, fiddling directly with LDAP implementation is to be avoided if possible in favour of sustainability. Therefore, custom interceptors (https://directory.apache.org/apacheds/advanced-ug/1.4-interceptors.html) were used to intercept LDAP API and hook it to Unity.

3.1.3. How to do it?

Unity defines a set of endpoints where we add our LDAPSserver

unityServer.core.endpoints.11.endpointType=LDAPServer
unityServer.core.endpoints.11.endpointConfigurationFile=conf/endpoints/ldap.properties
unityServer.core.endpoints.11.contextPath=/ldap
unityServer.core.endpoints.11.endpointName=Ldap info endpoint
unityServer.core.endpoints.11.endpointRealm=defaultRealm
unityServer.core.endpoints.11.endpointAuthenticators=pwdRaw

The server uses a new authenticator pwdRaw defined as

unityServer.core.authenticators.6.authenticatorName=pwdRaw
unityServer.core.authenticators.6.authenticatorType=password with raw-password
unityServer.core.authenticators.6.localCredential=Password credential
unityServer.core.authenticators.6.retrievalConfigurationFile=conf/authenticators/passwordRetrieval.json

The authenticator uses password with raw-password. Note that this names two classes responsible for the authenticator. Default password and our raw-password.

The binding is done dynamically through spring in components.xml as follows:

	<!-- LDAP server -->
	<bean class="pl.edu.icm.unity.ldap.endpoint.LdapEndpointFactory"/>
	<bean class="pl.edu.icm.unity.ldap.endpoint.RawPasswordRetrievalFactory"/>

RawPassowrdRetrievalFactory? is the raw-password in our configuration

@Component
public class RawPasswordRetrievalFactory implements CredentialRetrievalFactory
{
	public static final String NAME = "raw-password";

When Unity is started, the important part is done in

public class LdapEndpointFactory implements EndpointFactory

that defines (well, kind of again) the endpoint and later newInstance of this endpoint is called. This instantiates LdapEndpoint of which the getServletContextHandler method is called in which we start the embedded LDAP server and

        //
        RawPasswordRetrieval rpr = (RawPasswordRetrieval)(authenticators.get(0).getPrimaryAuthenticator());
        //
        startLdapEmbeddedServer(rpr);

The start of the LDAP server and the functionality is configured from ldap.properties file that looks like:

# leave empty for default server address
unity.ldapServer.host=192.168.2.4
# default ldap port is 389
unity.ldapServer.ldap_port=389
unity.ldapServer.ldaps_port=636
# hardcoded - unity.endpoint.ldapServer.bind.DN="uid=admin,ou=system"
unity.ldapServer.bind_password=XXX

unity.ldapServer.group_query=ougroups
unity.ldapServer.user_query=cn
unity.ldapServer.group_member=member
unity.ldapServer.group_member_user_regexp=cn
# return these attributes if the operation requests all user attributes
# e.g., values of SchemaConstants.CN_AT
unity.ldapServer.returned_user_attributes=cn,entryDN,jpegPhoto

The real logic is in LdapApacheDSInterceptor that implements interceptors for Apache DS LDAP API. Apache DS is threaded so these methods run in the context of Unity.

3.1.4. Few notes on integration

  • Apache -
        // Require ldap-user - cn should be enough
        // Require ldap-group - groups
        // Require ldap-dn - cn should be enough
        // Require ldap-attribute - not supporting
        // Require ldap-filter - not supporting
  • Drupal LDAP modules
  • one module defined and the other did not the attributes that should be returned

3.1.5. Notes in general

  • windows - IntelliJ Idea had to be configured like this (mvn package, added dependencies to other modules, disabled annotations, apacheds-service library (if used) had to be the last dependency)
  • apacheds-service library is a mess full of old libraries that conflict in runtime with unity (see above)
  • in order to use a new property, you have to define it in LdapServerProperties
  • simple LDAP drupal module used for debugging - https://github.com/vidiecan/drupal_simple_ldap
Last modified 7 years ago Last modified on 06/16/17 14:10:25