Shared out-of-context data
In general, the state of authentication processing is limited to the session of a user. Any state changes done within the context of a request (or by extension, within the conversation), which are not stored in the user's session, are lost when the operation has completed. In any case, data stored in these contexts can only be seen by operations running within the same context, that is, by the same user.
However, in some cases it is required to maintain a global state, which is not scoped to a particular user session and which can have a (much) longer lifetime. For this purpose, nevisAuth uses its shared out-of-context data service (OOCDS).
The out-of-context data service is provided by the OutOfContextDataService interface. It has the following properties:
- Storing key value pairs (many of the keys used look like file paths for historical reasons).
- Each entry has an associated expiration date and will not be visible after this date.
- Reading, writing, removing and querying entries is guaranteed to remain consistent under load of multiple accessing threads and processes. However, no guarantees are made regarding the performance of those operations.
Use Cases
The OOCDS interface is used in several cases, among others:
-
SAML
- To verify the uniqueness of received SAML messages.
- To look up a SAML artifact when an ArtifactResolve message has been received.
-
OAuth / OpenID Connect
- During the Authorization Code Flow.
-
Custom
- Custom Java based auth states may access OOCD.
- The ScriptState exposes this service via the scope OOCD.
- nevisAuth expressions may access OOCD.
It can generally be assumed that federation protocols are using the OOCDS.
Configuration
There are 3 available options:
- No OOCD is configured (default).
- In memory OOCD configured by
LocalOutOfContextDataStore. - SQL OOCD configured by
RemoteOutOfContextDataStore.
In case no OOCD is configured and the usage of OOCD is attempted an error will be thrown.
Interface
The OutOfContextDataService offers the following methods:
Set key-value pair(s):
void set(String key, String value, Instant notOnOrAfter)void set(Map<String, String> keyValuePairs, Instant notOnOrAfter)
Get key-value pair(s):
String get(String key)Map<String, String> getWithPrefix(String keyPrefix)
Remove key-value pair(s):
void remove(String key)void removeWithPrefix(String keyPrefix)
InMemoryOOCDService
The InMemoryOOCDService is a lightweight implementation to allow developers and integrators to use an OOCD to reduce integration / development time as it does not require a database.
The in-memory OOCD must not be used in production.
Configuration options:
-
reaperPeriod(string)Default value:
60The number of seconds how often the expired entries should be removed.
The InMemoryOOCDService can be configured in the esauth4.xml by the LocalOutOfContextDataStore element. The element must appear between the SessionCoordinator and AuthEngine elements.
Configuration example:
<LocalOutOfContextDataStore
reaperPeriod="60"/>
SqlOOCDService
The SqlOOCDService dataservice uses an SQL database as a backend to store out-of-context data. Currently, MariaDB and PostgreSQL databases are supported.
Database setup
The following steps outline the database setup required for classic deployments. This is not required in case you're using the Kubernetes-based setup.
- Create the connectionSchemaUser who has the rights to create the database table in a newly created database, then create the connectionUser who can modify the content of this table.
- You create the table by hand with the connectionSchemaUser.
- You rely on nevisAuth to use the connectionSchemaUserto create the table.
- Create the database table and the connectionUser with appropriate rights using an existing administrator user.
- Use an existing database.
- Create a new database by hand.
- Now create the database schema. If you want to store strings containing special characters, your database must use a charset supporting these special characters (e.g. UTF-8).
- Now create users to connect to the database.
Depending on your preferences, you can also re-use the NSS database and nss_auth user from the Remote Session Store setup (see chapter Session management. Note that in this case still create the user that will create the table, or you have to create the table manually by an administrator user.
It is not recommended using the same user for database table creation and data modification.
By default, the SqlOOCDService automatically creates the required database table in the SQL database (can be disabled by setting the connectionAutomaticDbSchemaSetup to "false"). The code below shows the current default table definition together with the initial setup:
MariaDB
CREATE DATABASE IF NOT EXISTS OOCD CHARACTER SET ='utf8' COLLATE ='utf8_unicode_ci';
CREATE USER IF NOT EXISTS `OOCDschemauser`@`localhost` IDENTIFIED BY 'password';
GRANT CREATE ON OOCD.* TO `OOCDschemauser`@`localhost`;
CREATE USER IF NOT EXISTS `OOCDdatauser`@`localhost` IDENTIFIED BY 'password';
GRANT SELECT, INSERT, UPDATE, DELETE ON OOCD.* TO `OOCDdatauser`@`localhost`;
FLUSH PRIVILEGES;
CREATE TABLE IF NOT EXISTS `nevisauth_out_of_context_data_service` (
`key` VARCHAR(1024) NOT NULL,
`value` MEDIUMTEXT NOT NULL,
`reap_timestamp` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
PRIMARY KEY ( `key`),
INDEX reap_timestamp_idx (`reap_timestamp`)
);
To allow remote connection you can replace the localhost with % to allow any host or with a specific host.
You can adapt the table above according to your needs, if your data exceeds the limits defined above (key size of 1024 bytes and storage size of 16 MB/MEDIUMTEXT), or fits into smaller data storage types like TINYTEXT or TEXT. Note that use the same table and column names.
Note that the key column size is 1024, but special characters can reduce the storage size.
MariaDB has a maximum index size limitation at 3072 bytes. This can vary based on db page size settings.
In an unlikely special case, where you only store 4 byte characters like emojis, you can only store 768 characters.
PostgreSQL
CREATE USER "OOCDschemauser" WITH encrypted password 'password';
CREATE USER "OOCDdatauser" WITH encrypted password 'password';
CREATE DATABASE OOCD
WITH
OWNER = "OOCDschemauser";
ALTER ROLE "OOCDschemauser" IN DATABASE OOCD SET search_path TO "OOCDschemauser";
ALTER ROLE "OOCDdatauser" IN DATABASE OOCD SET search_path TO "OOCDschemauser";
\connect OOCD "OOCDschemauser";
CREATE SCHEMA "OOCDschemauser" AUTHORIZATION "OOCDschemauser"
GRANT USAGE ON SCHEMA "OOCDschemauser" to "OOCDdatauser";
GRANT CONNECT ON DATABASE OOCD TO "OOCDdatauser";
ALTER DEFAULT PRIVILEGES FOR USER "OOCDschemauser" IN SCHEMA "OOCDschemauser" GRANT SELECT, INSERT, UPDATE, DELETE, TRIGGER ON TABLES TO "OOCDdatauser";
ALTER DEFAULT PRIVILEGES FOR USER "OOCDschemauser" IN SCHEMA "OOCDschemauser" GRANT USAGE, SELECT ON SEQUENCES TO "OOCDdatauser";
ALTER DEFAULT PRIVILEGES FOR USER "OOCDschemauser" IN SCHEMA "OOCDschemauser" GRANT EXECUTE ON FUNCTIONS TO "OOCDdatauser";
CREATE TABLE IF NOT EXISTS nevisauth_out_of_context_data_service (
key VARCHAR(1024) NOT NULL PRIMARY KEY,
value TEXT NOT NULL,
reap_timestamp TIMESTAMP WITH TIME ZONE NOT NULL
);
CREATE INDEX IF NOT EXISTS OOCD_reap_timestamp_idx ON nevisauth_out_of_context_data_service (reap_timestamp);
Configuring nevisAuth
The SqlOOCDService can be configured in the esauth4.xml by the RemoteOutOfContextDataStore element. The element must appear between the SessionCoordinator and AuthEngine elements.
The following list depicts the available configuration options:
-
connectionUrl(string)The JDBC URL to the MariaDB / PostgreSQL database. For more details regarding the syntax, see the MariaDB documentation and the PostgreSQL documentation.
infonevisAuth relies on the autocommit feature of the database.
- MariaDB requires to enable it on the database level or configure it in the JDBC driver url in this property using the query parameter
autocommit=true. - PostgreSQL by default have autocommit enabled.
For TLS connections, append TLS parameters to the JDBC URL.
MariaDB uses the
sslModeparameter (camelCase). For one-way TLS (server certificate verified against a CA):MariaDB one-way TLS examplejdbc:mariadb://server.sieven.ch:3306/database?sslMode=verify-caWhen using multiple hosts for resilience (sequential failover):
MariaDB sequential failover with one-way TLS examplejdbc:mariadb:sequential//server_1.sieven.ch:3306,server_2.sieven.ch:3306/database?sslMode=verify-caFor all available TLS options, see the MariaDB Connector/J TLS documentation.
PostgreSQL uses the lowercase
sslmodeparameter and requiresssl=true. For one-way TLS:PostgreSQL one-way TLS examplejdbc:postgresql://server.sieven.ch:5432/database?ssl=true&sslmode=verify-caFor all available TLS options, see the PostgreSQL JDBC SSL documentation.
- MariaDB requires to enable it on the database level or configure it in the JDBC driver url in this property using the query parameter
-
connectionUser(string)The username required to access the data in the database. This user must have SELECT, INSERT, UPDATE and DELETE access rights to the database. You can use the same format as for passwords. For example, you can use the following syntax to specify the username from an environment variable:
pipe://echo $SYNC_USER. For more information regarding the allowed syntax, see Passwords in the configuration. -
connectionPassword(string)The password of the user accessing the data. This property accepts standard encryption/obfuscation syntax. See documentation on how to restrict disclosure of passphrases in Passwords in the configuration.
-
connectionSchemaUser(string)The name of the user that creates the schema and tables in the database. This user must have CREATE access rights to the database. If not provided, the system will use the user specified with the attribute user to create the schema.
infoIt is recommended that separate users create the schema and access the data. You specify these users in the DB properties schemaUser and dataUser, respectively.
-
connectionSchemaPassword(string)The password of the user who creates the schema and the tables in the database. If not provided, the system will use the password specified with attribute password to create the schema.
-
connectionTimeout(boolean)Default value:
30000This property controls the maximum number of milliseconds that nevisAuth will wait for a connection from the pool.
-
connectionMaxLifeTime(Integer, msec, optional, 1800000)Default value: 1800000 (30 minutes)
The maximum time, in milliseconds, that a connection used in the connection pool.
-
connectionMinPoolSize(Integer, optional)Default value:
connectionMaxPoolSizeMininum number of connections in the connection pool used to connect to the database. In case this is set lower then
connectionMaxPoolSize, connections will be created on demand. -
connectionMaxPoolSize(Integer, optional, 10)Default value:
10Maximum number of connections in the connection pool used to connect to the database. Changing this value might require the changing of maximum allowed connection on the database server side.
-
reaperPeriod(boolean)Default value:
60The number of seconds how often the expired entries should be removed.
-
connectionAutomaticDbSchemaSetup(boolean)Default value:
trueIf set to "true", nevisAuth will automatically try to create the table used to store the data (with the CREATE TABLE IF NOT EXISTS syntax, as shown in the sample code snippet above).
Set this property to "false", if you want to handle this differently, for example because you have different data sizing requirements. Also set the property to "false", if you did not specify the schemaUser or if the specified user does not have the required CREATE access rights.
The next code block shows an example configuration to be added in the esauth4.xml.
<RemoteOutOfContextDataStore
connectionUrl="jdbc:mariadb://localhost:3306/OOCD?autocommit=true"
connectionUser="OOCDdatauser"
connectionPassword="password"
connectionSchemaUser="OOCD1schemauser"
connectionSchemaPassword="password"
connectionAutomaticDbSchemaSetup="true"/>
Below, find another example where we created the database table manually and reused the NSS database and the nss_auth user from the remote session store. Note that the connectionSchemaUser falls back to the connectionUser. So if the connectionUser has no CREATE rights, you have to disable the property connectionAutomaticDbSchemaSetup.
<RemoteOutOfContextDataStore
connectionUrl="jdbc:postgresql://localhost:5432/nss"
connectionUser="nss_auth"
connectionPassword="password"
connectionAutomaticDbSchemaSetup="false"/>