• Overview
  • What's new?
  • User Guide

What's on this Page

  • Activation
  • Configuration
    • Script loaded from file
    • Script loaded from resource
    • Script inlined in argument
  • Scripts
    • Script evaluation and behavior
    • Context object and interactions
    • Best Practices for Scripts
  • Bundled scripts
    • Generic Keycloak Login
    • Dump HTML Source
  • exense: oryon
  • User Guide
  • Syrius Login Automation
This article references one of our previous releases, click here to go to our latest version instead.

Syrius Login Automation

This page documents the usage of the JSLogin mechanism for external (Identity Provider-based) authentication to Syrius. Starting with Oryon 2.10.0, this is the recommended approach. Legacy Java-based implementations are still supported, and can still be used as long as they remain operational, but they are deprecated and no longer maintained. In any case, they can be replaced by the more flexible mechanism described here.

We recommend to start with the bundled authentication script that should work with Keycloak-based Identity Providers:

-Doryon.sso.credentials=username:password -Doryon.sso.implementation=ch.exense.oryon.modules.syrius.fx.sso.JSLogin -Doryon.sso.js.script=res:sso/keycloak.js 

In case this does not work, you will need a custom login script. You can implement one by following the documentation on this page, or contact us for support.

Activation

To use external authentication with Syrius, you need to specify the oryon.sso.implementation Java property with the value ch.exense.oryon.modules.syrius.fx.sso.JSLogin. This property is evaluated by the Oryon agent. In other words, it needs to be set in the same command that includes the reference to the Oryon agent and that launches the Syrius client. Here is a partial sample commandline showcasing it (it will look similar for the OryonDriver used in Step):

java -javaagent:.../oryon-agent.jar -Doryon.sso.implementation=ch.exense.oryon.modules.syrius.fx.sso.JSLogin ... 

The login procedure is not performed directly after the Syrius client application is launched, but rather at the moment where the Oryon agent (running inside the Syrius client application) is connected to (either by the Oryon Driver, or the IDE).

Therefore, when using the Oryon IDE for manual tests or recording scripts:

  1. Start the Syrius client with the appropriate Oryon login configuration. The login window will appear, but nothing will immediately happen.
  2. Start the Oryon IDE, and click the button to connect to the agent. The login will be performed at the moment this connection is established.

Configuration

Legacy external login implementations contain the complete logic about how to interact with the login page, compiled in Java code (which is why the ...implementation property exists in the first place, to be able to select different implementations depending on the login page).

The JSLogin implementation is flexible enough to interact with any login page – but just like Oryon scripts contain the automation logic to interact with the Syrius application, another kind of script is also required to interact with the login page. As the login is an HTML page, and the interaction is performed using a built-in browser component, it is natural to use JavaScript for the login automation script.

The JSLogin mechanism will determine the script to use from the oryon.sso.js.script property. If the JSLogin mechanism is used, this property is mandatory, and the Syrius client will be terminated if the property is not present or the script cannot be loaded correctly. There are multiple possibilities to define the script source, each with their own advantages and disadvantages, presented in the following:

Script loaded from file

This is the most obvious and straightforward way to specify a script, and it simply uses the given file as the source of the script. It is activated by setting the script property to file:, followed by the name of the file. For example:

java [...] -Doryon.sso.js.script=file:/home/user/oryon/login.js [...]

The definition above will attempt to load the file /home/user/oryon/login.js as the login script to execute. We strongly recommend to use absolute path names for the files.

Advantages:

  • Most natural and understandable way to specify script location
  • Especially useful while developing and testing the scripts because it allows for quick iterations

Disadvantages:

  • Script file must be present in the filesystem of the host where the oryon agent is started, which may pose a challenge in containerized infrastructures

Script loaded from resource

By setting the script property to res: followed by a resource name, the implementation will load the script source by using Java’s classloader mechanism to look up the respective resource. For instance:

java [...] -Doryon.sso.js.script=res:sso/keycloak.js [...]

The above definition will load the sso/keycloak.js resource, which is basically a file contained directly in the oryon-agent jar itself. In other words, Oryon already ships with this generic script built-in, which should be able to handle most Keycloak-based login pages.

Advantages:

  • Does not require additional files, but uses resources bundled directly with Oryon
  • Official distribution contains generic script for standard Keycloak-based logins
  • Custom scripts can be bundled by simply adding them to the oryon-agent.jar (Note: jar files are really just zip archives, so it’s easy to modify them)

Disadvantages:

  • Requires changing Oryon jar files for inclusion of custom scripts
  • Not suitable for rapid iterations, but rather for inclusion after development is finished

Script inlined in argument

The final possibility to define the script is to basically specify the script content directly as the parameter value. This is possible by simply encoding the entire script using Base64 (so it can be safely used as a parameter value) and directly setting the script property to that value, prefixed by base64:. For example:

-Doryon.sso.js.script=base64:b3J5b24ubG9nKCJIZWxsbyB3b3JsZCEiKTs

The example above will be decoded to the script content:

oryon.log("Hello world!");

Note that this is indeed a functional script in the sense that it will be executable, but it will obviously not perform any login actions.

The decoder accepts both standard (base64) and URL-safe (base64url) variants of Base64 encodings, and padding is not required but supported. We recommend to use the URL-safe encoding, without padding, because it will not produce characters that might interfere with the command or shell parsing.

There are plenty of tools or online pages to encode text as Base64; for a quick conversion, we recommend this page (check both “URL-safe” and “No padding” checkboxes to get the recommended result).

Advantages:

  • No need to provision additional files or modify Oryon jars
  • Rather quick and easy to update if needed

Disadvantages:

  • Trivially decodable (might be relevant in case of sensitive content)
  • Safe for small scripts up to ~6 kB on all OS, support for larger argument lengths is OS-dependent

Scripts

Please read this entire section before attempting to implement a script, as there is some important information about the behavior and best practices in multiple parts.

Without further ado, below is the source code of the bundled Keycloak script (included with Oryon and usable as res:sso/keycloak.js) for reference. It should be straightforward to understand and can serve as reference for some of the discussion below:

(function() {
    function get(id) { return document.getElementById(id); }
    get('username').value=oryon.credentials.username;
    get('password').value=oryon.credentials.password;
    oryon.setStatus("DONE");
    get('kc-login').click();
})();

Script evaluation and behavior

Before implementing a script, it’s important to understand when and how it is invoked, and how it interacts with the page and the Oryon environment.

The external login phase consists of three logical steps:

  1. Wait until a login window appears.
  2. Execute login script.
  3. Wait until the login disappears.

Each of these steps is repeatedly attempted in 500 ms intervals until it either succeeds, in which case execution passes to the next step, or the step fails or times out (after a total of max. 10 seconds for each step).

The login is only considered successful if all 3 steps pass. Only the second step actually uses the script. The logic is as follows:

  1. Once the page is loaded, the oryon context object is injected, directly followed by the execution of the script.
  2. If and only if the oryon context object’s status equals DONE, the script is considered successfully executed and the login passes to step 3 (wait for window to disappear).
  3. If the oryon context object’s status field is set to a value starting with ERROR, the login is considered failed and is immediately aborted with the respective status as the error message.
  4. If none of the aforementioned happened, this iteration is considered finished and another step iteration will be reattempted later.

Context object and interactions

The context object that is injected into each page is called oryon and offers the following fields and methods to use within the JavaScript context:

  • oryon.log(String arg): This can be used to log messages to the logger of the Syrius process. Logs are emitted at loglevel INFO and prefixed with [JS log]: .
  • oryon.setStatus(String arg): The status is evaluated at the end of the script execution and handled as explained above. In short, DONE signals success, ERROR signals failure; any other values are ignored.
  • oryon.credentials.username and oryon.credentials.password: These are values that are provided to the script and can be used to fill the username and password fields.

Note that the oryon.credentials object will ONLY be set if credentials are actually defined using a command-line property:

-Doryon.sso.credentials=username:password 

You may omit these credential definitions in case you do not want to expose them on the command line, however in that case the oryon.credentials object will remain null , and you will need to hardcode the credentials in the script.

Best Practices for Scripts

Script evaluation and execution scope

It is important to realize that your script may be repeatedly executed, and potentially on different pages (for instance if you need to first navigate to a second page where the credentials can be filled). It is your duty as a script implementer to ensure that you correctly recognize the context (if applicable), and that your script can be repeatedly invoked.

The best way to ensure side-effect-free repeated executions is to simply wrap the entire script in an anonymous function that gets executed. This is exactly what the included scripts also do:

(function() {
    // actual script code goes here
})();

This ensures that for instance variable declarations stay local to the anonymous (“throwaway”) context. If you omit the wrapping function, variable declarations would end up being executed in the global page scope, and could cause errors on repeated invocations – because the declaration would become a conflicting re-declaration of an existing variable.

Setting return statuses

While developing a script that performs a successful login, you will always have one final action (usually a click() that results in a form submission) which causes the login window to disappear – precisely because the login was successful.

In order to guarantee that the final status correctly gets transmitted on script execution, even if the window – and therefore the context the script works in – is being destroyed, it is safest to set the status before the final action. In other words, while this code sequence is more intuitive:

get('kc-login').click();
oryon.setStatus("DONE");

… this one is safer:

oryon.setStatus("DONE");
get('kc-login').click();

Note that in case the click() would not actually perform a successful login for some reason (i.e., not closing the login window), the login procedure would simply fail in step 3 (wait for window to disappear), which happens after the script execution.

JavaScript language level and features

Syrius uses JavaFX, and the Login window is implemented using the Browser component that is bundled with the Java version you are using to run Syrius. With a decently modern Java version (17+), all features of the ES6 (ECMAScript 2015) standard can be used. While a significant part of newer language features may also be supported depending on the exact Java/Webkit version, ES6 should be amply sufficient for simple login scripting, so we recommend to play it safe and stick to that language level.

Bundled scripts

Out of the box, Oryon comes bundled with two scripts to facilitate development and getting started with writing your own scripts.

Generic Keycloak Login

This script is activated using -Doryon.sso.js.script=res:sso/keycloak.js and should be able to handle most simple keycloak-based login screens like Azure/Microsoft single-factor authentication. Note that the credentials to be used must be defined as a command-line argument (see above).

Source code:

(function() {
    function get(id) { return document.getElementById(id); }
    get('username').value=oryon.credentials.username;
    get('password').value=oryon.credentials.password;
    oryon.setStatus("DONE");
    get('kc-login').click();
})();

Dump HTML Source

This script is not an actual login script, but it can help as a first step when you are confronted with an “unknown” login page. Syrius does not disclose the URL of the login page, nor its source code, so it may be difficult to even get started.

Using this script ( -Doryon.sso.js.script=res:sso/dump.js ) will instantly abort the login with an artificial error – but crucially, the error message is a dump of the login page’s HTML code.

Source code:

(function() {
oryon.setStatus("ERROR: HTML dump\n" + document.documentElement.outerHTML);
})();

A less “destructive” way to extract information from the JavaScript context is to use the oryon.log() method that might also be useful while developing or debugging scripts.

  • Overview
    • Overview
    • Oryon Agent
    • Oryon IDE
    • Integration with step
  • What's new?
    • Release Notes
  • User Guide
    • IDE Settings
    • Parameter Input
    • Logging
    • Syrius Single Sign On
    • Syrius Login Automation
    • API Documentation
    • Syrius Node Pruning
Step Logo
    • Overview
    • What's new?
    • User Guide
    • Overview
    • What's new?
    • User Guide