T1C-JS-Belfius Guide
Initial version
Initial version
  • Introduction
  • Core
    • Introduction
    • Concepts
    • Source Code
    • Overview Client API
    • Client Configuration
    • Core Services
    • Consent
    • Agents
    • Generic Interface
    • Configuration
    • Installation
    • Status codes
    • Troubleshooting
  • Containers
    • Remote Loading
    • Belfius Reader
    • Belgian eID
    • EMV
    • File Exchange
Powered by GitBook
On this page
  • Introduction
  • Flow
  • Agent Resolution
  • Agent resolution by selection
  • Implicit Agent Resolution
  1. Core

Agents

PreviousConsentNextGeneric Interface

Last updated 6 years ago

Introduction

In a Citrix environment, there is one Trust1Connector core service, running on the main machine, and one or more agents, one for each user session, which registers itself on the core service. The core service then acts as a proxy, relaying requests to specific agents as needed.

When running in Citrix mode (citrix == true in the configuration), the core Trust1Connector service will not allow access to any endpoint other than the agent list.

In order to communicate with an agent, we must determine which agent we want to use (this is up to the application), and then re-initialize a client library with the agentPort of our target agent. This will redirect all requests to this agent.

Flow

Agent Resolution

In order to determine the agent port used by the library, 2 mechanism are set in place:

  • Agent resolution by selection: retrieve the agent port based on environment variables registered by agent upon startup (user session initialization). The user must select the correct agent in this use case.

  • Implicit Agent resolution: retrieve the agent implicitly by executing the resolve agent use case, the central instance will trigger all registered agents to verify the reception of a challenge generated by the application on the user's clipboard; this flow persist a user ID token in the browser storage in order to reuse already resolved agents. The user must perform a user gesture to copy the challenge to his clipboard.

Agent resolution by selection

Retrieving agent list

The agent list is managed by the core Trust1Connector service, and is the only endpoint that is accessible on this instance of Trust1Connector.

To retrieve the list, we initialize a GCLClient instance without agent port, which will communicate directly with the core T1C.

var config = new GCLConfig();

GCLLib.GCLClient.initialize(config, function(err, client) {
    // client returned is initialized for use with the core Trust1Connector
    // can only be used for retrieving agent list
});

Once this is done, we can retrieve the agent list:

client.agent().get().then(result => {
    // result contains the full list of agents
});

A typical result looks like this:

{ "data": [{
    "hostname": "hostname",
    "last_update": "2017-09-01T00:00:00.000000",
    "metadata": {},
    "port": 56789,
    "username": "username"
    }],
"success":true }

It contains an array of all the agents known to the system. It is also possible to filter the list of results, by passing in a filter object:

client.agent().get({ username: 'username' }).then(result => {
       // result contains only agents matching the username
});

The filters will be matched to the username and metadata properties of the agents, and only matching agents will be returned.

Once the list of agents is retrieved, the application selects the agent to use from the list. For this agent, we initialize a new client that will communicate only with the selected client by passing in the port in our config.

Initialize agent client

Once we have determined the agent port to use, we can initialize the agent client as follows:

var agentPort = 56789 // example agent port
var config = new GCLConfig();
config.agentPort = agentPort;

GCLLib.GCLClient.initialize(config, function(err, client) {
    // client returned is initialized for use with the agent on port 56789
    // should be used for all subsequent calls
});

The new client will now only communicate with the selected agent, and should be used for all subsequent calls.

Implicit Agent Resolution

For this use case, the list of registered agents must not be requested. Prior to this use case, the application has generated a challenge, and the user has done a gesture in order to copy the challenge on his clipboard.

The following diagram depicts both sequence diagrams:

After the user gesture event, the application requests the agent resolution:

client.agent().resolve({ challenge: 'appchallengevalue' }).then(result => {
       // result contains the matching agent who found the challenge on user's clipboard with environment variables registered.
});

This will trigger initially a check in the browser context, to search for an user ID token stored in the browser. If the user ID token is available, the user ID token will be converted to the user's environment variables and passed to agent's request as a filter:

client.agent().get({ username: 'username' }).then(result => {
       // result contains only agents matching the username
});

A typical result looks like this:

{ "data": [{
    "hostname": "hostname",
    "last_update": "2017-09-01T00:00:00.000000",
    "metadata": {},
    "port": 56789,
    "username": "username"
    }],
"success":true }

The filters will be matched to the username and metadata properties of the agents, and only matching agents will be returned.

For this agent, we initialize a new client that will communicate only with the selected client by passing in the port in our config.

Initialize agent client

Once we have determined the agent port to use, we can initialize the agent client as follows:

var agentPort = 56789 // example agent port
var config = new GCLConfig();
config.agentPort = agentPort;

GCLLib.GCLClient.initialize(config, function(err, client) {
    // client returned is initialized for use with the agent on port 56789
    // should be used for all subsequent calls
});

The new client will now only communicate with the selected agent, and should be used for all subsequent calls.