Skip to main content

Security in a Distributed Environment

In this article, we shall consider that each member of a cluster is a distributed cube. Moreover, we may use interchangeably the terms: distributed cube, member, or node to describe a member of the cluster. The last two terms are in line with the JGroups terminology, and arguably with distributed architectures in general.

Security in a distributed cluster, and more specifically access permission, can be handled within Atoti.

There are two types of security you have to consider when working with a distributed cluster:

  • Cluster Security, a security layer designed to prevent unwanted cluster members from connecting to the cluster.
  • User Security, a security layer designed to prevent a given user from authenticating to a specific node, which lets the developer take advantage of the Authentication Policies relevant for the Atoti application instance hosting that cube.

Cluster Security

The first security layer is designed to prevent unwanted members from joining a given distributed cluster.

It is already embedded within JGroups, the third-party library implementing the communication layer that Atoti leverages for its distributed architecture feature.

The Key-Based Authentication Token

Users have to define a key (as a String) in the JGroup configuration file (by default, protocol.xml).

The protocol layer then encrypts this key, and adds it as a header in the JOIN_REQUEST messages sent by all the cubes to join the cluster. A member whose key does not match the keys of the registered members will receive a security error and be treated as undesired.

For this reason, all members of a cluster must be configured with the same private key within their respective protocol.xml configuration file.

For each cube, three additional parameters must be specified:

ParameterDescription
auth_classThe location of the class that defines the security layer. Format: packageName.ClassName, as a string.
auth_valueThe key to encrypt, as a string.
token_hashThe name of the algorithm used to encrypt the key. MD5 and SHA are available.

Configuration example:

<config>
...
<AUTH auth_class="com.activeviam.activepivot.dist.impl.internal.distribution.security.impl.CustomAuthToken"
auth_value="password"
token_hash="MD5"/>
...
</config>

You can also use any of the classes defined by JGroups, detailed here.

Customization

Atoti fully supports Cluster Security customization. To create a security layer mechanism, follow these steps:

  1. Create a new class that extends org.jgroups.auth.AuthToken.

  2. Define the desired attributes and their setters.

    class MyAuthToken extends org.jgroups.auth.AuthToken {
    protected String auth_value = null;
    protected String hash_type = "MD5";

    @Property
    public void setAuthValue(String auth_value) {
    this.auth_value = encrypt(auth_value);
    }

    @Property(name="token_hash")
    public void setHashType(String hash_type) {
    this.hash_type = hash_type;
    }

    ...
    }

    The @Property annotation is mandatory

  3. Implement the authenticate method, which validates if a node can join the cluster or not.

  4. Implement an encrypt method if the user wants to encrypt the key.

  5. Implement the getName method to return this.getClass().getName() (mandatory).

  6. Implement #writeTo(...) and #readFrom(...) to serialize the token.

  7. Match the protocol.xml fields with the correct attributes defined in the custom class.

Simultaneous Authentication Mechanisms

You can define more than one authentication method in the protocol.xml file. To do so, each AUTH element must have an id attribute with a unique integer value.

User Security

Unlike Cluster Security, User Security has nothing to do with JGroups. It is related to Atoti's usual authentication policy, the user's authentication to the data nodes.

First the user authenticates on a query node. The current implementation then forwards the username to every other node in the cluster (the nodes that have cleared the Cluster Security layer) relevant for each of the user's requests. This approach requires the user to authenticate on all the different Atoti applications.

User Roles

Atoti's distributed architecture is seamlessly able to use the authorization mechanisms defined outside of the distribution environment, which means that no additional configuration is required other than the one already defined on a single cube.

A IUserDetailsService is still needed in a distributed environment. Atoti needs to retrieve a user's information from his username, in case his permissions vary on an application basis.