Opmantek Applications released after 22 Feb 2017 support a new authentication method called
token, which offers delegated authentication: an external party can pre-authenticate a user, who can access the Opmantek applications without having to log in with username and password.
How does it work?
The core idea is broadly similar to Kerberos: the Opmantek application and the external party share a cryptographic key, and thus a trust relationship is established. When the external party is satisfied that a user should be (pre-)authenticated for Opmantek apps, then it uses that shared key to create a 'token' or 'ticket', which the user can present to the Opmantek application in lieu of logging in interactively; if the ticket verifies as valid, the Opmantek application accepts the user as authenticated and logged in.
To enable token authentication, a few configuration settings must be added to
- One or more shared keys must be set up,
- optionally, the maximum validity for tokens may be specified,
- and finally, the authentication method
tokenmust be added as one of the three supported authentication methods.
Once these changes are made, the Opmantek daemon must be restarted (
sudo service omkd restart) to activate them.
Here is an example
opCommon.nmis snippet, showing just the relevant items:
auth_token_key list specifies which shared keys should be accepted and tried in sequence. Setting just one key is ok. If you have multiple external parties that you want to delegate authentication duties to, then it is recommended that you give each their own key.
auth_token_maxage setting must be a positive number, and defines how long a token remains valid after creation (in seconds). If not present, the default of 300 seconds is used.
token authentication method is active if and only if one of the
auth_method_1, 2 or 3 entries is set to
token. Please note that it is not relevant which of the three is set to token; the
token method is ignored when the normal username and password login form is used, and conversely the other methods are ignored if the token access URL is visited (see next section).
Generating a Token
Opmantek applications released after May 2017 ship with a small token generator helper in
/usr/local/omk/bin/generate_auth_token.pl (and also compiled into a standalone
.exe program, in the same location).
This token generator must be passed the shared key to use, and the username to generate a token for. The encrypted token is created with and for that username and contains the current time (in UTC). Finally, the generator prints the resulting token, as in the following example:
Token length varies depending on the username, and each execution does create a different token. Please note that if your shared key contains shell metacharacters (like "!" in the example above) you will have to quote them with single quotes when passing them to the token generator.
Logging in with a Token
To use a token with an Opmantek application, the token generating party should direct the user to a URL in the following format:
As a concrete example, to access opCharts with the token from before we'd use
If your system is configured for secure HTTP then it's fine to use
https://. Token authentication works for all commercial Opmantek applications (e.g. application keys
opConfig and so on).
When the user accesses this URL using their browser, the authentication subsystem detects the presence of a token and attempts to verify it. If a suitable shared key was configured on the receiving system, and if the token could be decrypted and is not too old, then authentication succeeds, suitable cookies are created and returned, and the user is redirected to the main page for the given application.
If the token is invalid, the user is shown the classic login form, with a suitable error message.
If you need to direct the user to a particular page rather than their Default page/Dashboard you can extend the authentication URL with "?redirect_url=" for example with the token above we can direct someone directly to the topn page as follows:
Once the client has accessed the first page, they have been issued auth cookies and all standard URLs work without the token string in the URL. You will want to consider how the user is handled to re-authenticate them if the session expires.
Token Content and Interoperability Notes
The "payload" data of the token consists of
- the current time (in UNIX seconds since 1970, timezone UTC) as a string (e.g. "1487738312")
- a single space character,
- and the respective username (which must contain printable ascii characters only; e.g. "nmis" or "john doe").
This data is then encrypted symmetrically using the shared key, with the following parameters:
- AES with 128-bit key size in CBC mode,
- block-padded to the normal 128-bit block size using the standard PKCS#5 padding format,
- with OpenSSL-compatible salted header format,
- and using an OpenSSL-compatible password -based key and IV derivation function (PBKDF).
Please note that the shared
auth_token_keyis used as passphrase to derive the actual key, not as a literal binary 128-bit key.
The resulting encrypted data is binary, and must be encoded for use as a URL component.
The encoding is a trivial hex-encoding: each binary byte is replaced by its representation as two hexadecimal digits.
- The token authentication system does not support locking out users after N unsuccessful login attempts.
- As the token contains the current time at the creating system and is valid for a limited time only, reasonably precise time synchronisation is critical for this method to work.
If a token could be decrypted but was rejected because it was deemed too old, then a suitable log entry is written to the
- Tokens are not single-use: a token works any number of times as long as it is presented within the configured validity period.
Code Examples for Token Generation
The following block contains essentially the same code as the token generator shipped as
Shell using the OpenSSL CLI
The following small shell script requires the
openssl command line tool and
hexdump to perform the token generation (with the key being the first argument, username second):
Python's pycrypto module should contain everything required, except the OpenSSL-specific PBKDF which can be found here.