Configuring Alfred Edge

Alfred Edge builds on Spring Boot. Like in Spring Boot, the configuration in Alfred Edge can be externalized, so the same application can be configured differently in different environments. Alfred Edge can be configured using properties files, YAML files, environment variables and command-line arguments.

Properties are considered in the following order:

  1. Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
  2. Command line arguments.
  3. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
  4. JNDI attributes from java:comp/env.
  5. Java System properties (System.getProperties()).
  6. OS environment variables.
  7. Profile-specific application properties outside of your packaged jar (application-{profile}.yaml or application-{profile}.properties).
  8. Application properties outside of your packaged jar (application.yaml or application.properties).
  9. The default Alfred Edge application properties packaged inside the .jar in edge.yaml.

In practice this means when running in a new environment, an application.yaml file can be provided outside of the edge-app.jar that overrides the default settings. Environment- or profile-specific settings can be loaded from application-{profile}.yaml. For one-off testing, you can launch with a specific command line switch (e.g. java -jar edge-app.jar --server.address.port=8081).

Configuring Alfred Edge on Tomcat Application Server

Loading in an external configuration when deploying on a Tomcat Application server can be done in two ways.

Deploying in your Tomcat installation folder

When deploying edge in Tomcat, you can put your configuration in the ${CATALINA_HOME}/lib/config folder. If you place your configuration in this directory, Edge will automatically pick it up and load it.

Deploying in a custom directory

When using Tomcat, it is possible to place the configuration in a custom directory. To allow Edge to find the configuration, add the -Dspring.config.location variable to CATALINA_OPTS. If spring.config.location contains directories (as opposed to files) they should end in / (and will be appended with the names generated from spring.config.name before being loaded, including profile-specific file names). Files specified in spring.config.location are used as-is, with no support for profile-specific variants, and will be overridden by any profile-specific properties. The spring.config.name defaults to edge.

Routes

Simple routing filter

Routes requests to a configured url.

Configuration

zuul:
  routes:
    alfresco:
      path: /alfresco/**
      url: http://localhost:8081/alfresco
    share:
      path: /share/**
      url: http://localhost:8081/share

The path parameter is optional. If no path parameter provided, all requests to the service name will map to the url.
E.g. following configuration will route all /alfresco/** requests to http://localhost:8081/alfresco

zuul:
  routes:
    alfresco:
      url: http://localhost:8081/alfresco

Ribbon routing filter

Routes requests through Ribbon services

Configuration

zuul:
  alfresco:
    path: /alfresco/**
    stripPrefix: false
    serviceId: alfresco
  share:
    path: /share/**
    stripPrefix: false
    serviceId: share

alfresco:
  ribbon:
    listOfServers: alfresco1.xenit.eu, alfresco2.xenit.eu
share:
  ribbon:
    listOfServers: localhost:8081

With this example configuration, all trafic to /alfresco/ will be routed to the alfresco Ribbon service. In this example, this is a load balancer between an alfresco1 and alfresco2 host.

By default, ribbon services have a connection- and read timeout of 1000ms. To change this timeout for all services, add following configuration: (time in milliseconds)

ribbon:
  ConnectTimeout: 3000
  ReadTimeout: 60000

To change this timeout for a specific ribbon service, add following configuration:

<serviceName>:
  ribbon:
    ConnectTimeout: 3000
    ReadTimeout: 60000

Configuring hystrix

The Ribbon router uses hystrix and the default timeout for hystrix is 1000ms. Hence when using Ribbon routing, it is possible that this timeout limit is insufficient.

To solve this, we can configure hystrix to

  • disable hystrix timeout globally:
    hystrix.command.default.execution.timeout.enabled: false
  • disable hystrix timeout on service level:
    hystrix.command.<serviceName>.execution.timeout.enabled: false
  • set hystrix timeout globally:
    hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
  • set hystrix timeout on service level:
    hystrix.command.<serviceName>.execution.isolation.thread.timeoutInMilliseconds: 60000

Authentication

The authentication system in Alfred Edge requires requests passing through to be authenticated. Alfred Edge can act as a central authentication point in the system architecture. User identity can be securely propagated to the backend services, with a secure & signed JWT token.

Integration with a range of authentication systems is available. Currently the following authentication systems are fully supported:

  • LDAP
  • Active Directory
  • In memory user-store
  • Alfresco

If integrating Alfred Edge with only one of these systems is not sufficient, multiple authentication protocols can be combined together. Multiple instances of the same authentication protocol can also be combined, if for example your authentication architecture requires multiple LDAP-servers to be consulted.

Authentication and identity management functionality is provided by a prioritized list, or chain, of configurable authentication protoocols. The built-in authentication chain is a priority-ordered list of authentication system instances.

An authentication system provides the following functionality to Alfred Edge:

  • Authenticate a (web-)request, usually by veryfying user credentials
  • Provide information about the users’ role or group

It is NOT possible to use Alfred Edge to authenticate CIFS or IMAP protocols.

LDAP

Overview

LDAP is often used by organizations as a central repository for user information and as an authentication service. It can also be used to store the role information for application users.

Alfred Edge uses Spring Security & Spring LDAP internally to support many different LDAP configuration scenario’s.

Using LDAP with Spring Security

LDAP authentication in Spring Security can be roughly divided into the following stages.

  • Obtaining the unique LDAP “Distinguished Name”, or DN, from the login name. There are two scenario’s supported:
    • If the exact mapping of usernames to DNs is known in advance, this can be a straight forward user-DN-pattern, such as uid=joe,ou=users,dc=xenit,dc=eu.
    • Otherwise this will mean performing a search in the directory.
  • Authenticating the user by “binding” as that user.
    • Spring Security supports performing a remote “compare” operation of the user’s password against the password attribute in the directory entry for the DN, but this functionality is currently not exposed in Alfred Edge.
  • Loading the list of authorities for the user.

Configuring LDAP Authentication

There are two properties to configure:

  • authentication.ldap.url: the url of the LDAP server(s).
  • authentication.ldap.base: the base suffix from which all operations should origin. If a base suffix is set, you will not have to (and, indeed, must not) specify the full distinguished names in any operations performed.

Example:

authentication:
  ldap:
    server:
      url: ldap://localhost:8389
      base: dc=xenit,dc=eu
Using Bind Authentication

This is the most common LDAP authentication scenario.

authentication:
  ldap:
    userDnPattern: uid={0},ou=people

This simple example would obtain the DN for the user by substituting the user login name in the supplied pattern and attempting to bind as that user with the login password. This is OK if all your users are stored under a single node in the directory.

If instead you wished to configure an LDAP search filter to locate the user, you could use the following:

authentication:
  ldap:
    userSearchFilter: (uid={0})
    userSearchBase: ou=people

If used with the server definition above, this would perform a search under the DN ou=people,dc=xenit,dc=eu using the value of the user-search-filter attribute as a filter. Again the user login name is substituted for the parameter in the filter name, so it will search for an entry with the uid attribute equal to the user name. If user-search-base isn’t supplied, the search will be performed from the root.

Active Directory

Active Directory has its own authentication mechanism, that differs from the LDAP-standard.

Typically authentication is performed using the domain username (in the form user@domain), rather than using an LDAP distinguished name. To make this easier Alfred Edge has explicit Active Directory authentication support, which is a customized version of the more generic and standardized LDAP authentication.

If the ldap-ad authentication system is properly configured, a user can log in with its username or with his full AD principal name (user@domain.com).

Configuring LDAP-AD Authentication

The domain and url configuration parameters are required to configure the ldap-ad authentication system.

  • The domain: when a user logs on with its user name, the AD principal name for this user will be constructed by appending the domain. For example: if the domain property is configured to mydomain.com and a user will login with username sharon, Alfred Edge will use sharon@mydomain.com to authenticate against AD.
  • The url: this specifies the ldap://-url where the Active Directory server can be accessed.
  • the baseDN: (optional) this is the root for the search when locating the user-object. This parameter is optional and by default this is automatically derived from the domain.

Example configuration:

authentication:
  chain:
    - ad1:ldap-ad
  ad1:
    domain: mydomain.com
    url: ldap://ldap-ad.example.com
    baseDn: dc=mydomain,dc=com

In Memory User Authentication

The “In Memory User Authentication” is an internal authentication system, which makes it possible to authentication against a preconfigured user registry.

This authentication system is primarily inteded for testing purposes.

Configuring In Memory Authentication

The in memory user authentication configuration will be explained based on following example configuration.

authentication:
  chain:
    - mem1:mem
    - mem2:mem
  mem1:
    encoder:
      type: bcrypt
    defaultRoles: USER, INFLOW_ADMIN
    users:
      - id: toon
        password: $2a$10$qWbu.Kt1wiQNTRkQeAebzul1osGIA27zBjXQHOcn4Hslg/xe2nqNu # = password
        roles: ADMIN
  mem2:
    encoder:
      type: plaintext
    defaultRoles: USER, INFLOW_ADMIN
    users:
      - id: piet
        password: password
        roles: ADMIN
Enabling the in memory user authentication

To enable the in memory user authentication, we need to add an authentication of type mem to the authentication chain.

Encoder

The encoder type specifies which encoder is used to encrypt the password of the users.

Supported encoder types:

If no encoder configuration is specified, the default encoder (bcrypt) will be used.

DefaultRoles

This configuration specifies the default roles that are applicable for all users of this in memory user registry.

Users

Specify all the users of this in memory registry. Each user has an id and a password that should be encrypted according to the configured encoder. Additionally a user can have roles.

Alfresco Authentication

This authentication system delegates the authentication to an existing Alfresco system.

The intended use case is to support the migration from an existing Alfresco system to Alfred Edge, where the user-database is managed in Alfresco.

Working Principles

When a user provides credentials in the request to Alfred Edge, this authentication system will use those credentials to request an authentication token (alf_ticket) from Alfresco. If Alfred Edge is able to get an authentication ticket, the user is considered authenticated in Alfred Edge.

This authentication system uses the /service/api/login endpoint to verify the credentials and request and authentication ticket.

Configuring Alfresco Authentication

In application.yaml in Alfred Edge:

authentication:
  chain:
    - alfresco1:alfresco
  alfresco1:
    server: http://localhost:8081/alfresco

To configure the Alfresco authentication:

  1. Create an Alfresco configuration block (alfresco1 in the example).
    The only thing that needs to be configured is the server. The value is the url of the Alfresco server that should be used for the authentication. This server url should end with /alfresco.
  2. Add the Alfresco authentication to the authentication chain.

Note: to make this authentication schema to work properly, the authentication.chain in Alfresco needs to be configured with at least one other (username/password-based) authentication subsystems.

For example (in alfresco-global.properties):

authentication.chain=external-jwt:external,alfrescoNtlm1:alfrescoNtlm

Access Logs

The access logs show the processed requests. The content and the format of this logging can be configured.

Configuration

server:
  tomcat:
    accesslog:
      enabled: true
      pattern: '%t %{username}r "%r" %s (%B bytes; %D ms)'

Standard pattern identifiers are explained in the Tomcat Documentation.

To log the name of the authenticated user, the expression %{username}r can be used.

Available properties to specify the Tomcat behaviour, including the properties for the access log, can be found in the Spring Boot Documentation. All Tomcat specific properties have a name starting with server.tomcat.