When a user's ThinLinc session starts through Open OnDemand, ThinLinc needs to authenticate the user before granting access to the desktop. There are two supported options:
- No automatic login: the user is presented with the ThinLinc Web Access login prompt and authenticates manually.
- OIDC authentication (requires ThinLinc >= 4.21): the user is authenticated via an external identity provider (such as Keycloak) configured in ThinLinc. This is the recommended option for environments that already use an identity provider.
Choose the option that best fits your environment. Which option is used is
controlled by the auth_method variable in view.html.erb, which defaults to
"manual". Set it to "oidc" for the OpenID Connect support.
This is the default behaviour and requires no additional installation. With
auth_method = "manual" in view.html.erb, the "Connect using the browser"
button simply opens ThinLinc Web Access, and the user authenticates at the Web
Access login prompt with their own system credentials.
With this option, clicking "Connect using the browser" redirects the user to an external identity provider for authentication. After the provider verifies the user's credentials, ThinLinc authorizes the user through PAM and starts the session.
ThinLinc derives the OIDC redirect URI from the browser's current URL. When
users reach Web Access through OOD's reverse proxy, the redirect URI contains
the /secure-rnode/HOST/PORT/ path, which varies with each Slurm allocation.
If your compute node URLs are static, any OIDC provider works. Register each
redirect URI explicitly. If they are dynamic, the provider must support wildcard
redirect URIs (https://<portal>/secure-rnode/*). Keycloak supports this
and is explicitly documented by ThinLinc.
Register ThinLinc as an OIDC client in your provider (Keycloak example follows):
- Client authentication: Confidential (on)
- Authentication flow: Standard flow (authorization code)
- Valid redirect URIs:
https://<ood-portal>/secure-rnode/* - Scopes:
openid profile(adjust based on your username claim)
Collect the client ID, client secret, and discovery URL from your provider.
Add the provider to /opt/thinlinc/etc/conf.d/webaccess.hconf:
[/webaccess/oidc/keycloak]
username_claim=preferred_username
discovery_url=https://<provider-host>/realms/<realm>/.well-known/openid-configuration
client_id=<client-id>
client_secret_path=/opt/thinlinc/etc/tlwebaccess/client_secret.txt
scope=profileStore the client secret in a file with restricted permissions:
echo -n '<client-secret>' | sudo tee /opt/thinlinc/etc/tlwebaccess/client_secret.txt
sudo chown root:root /opt/thinlinc/etc/tlwebaccess/client_secret.txt
sudo chmod 600 /opt/thinlinc/etc/tlwebaccess/client_secret.txt
Restart ThinLinc services after making changes.
When ThinLinc redirects the browser to the OIDC provider (such as Keycloak), the
response is a 302 with an absolute URL in the Location header pointing at
the provider. OOD's rnode proxy rewrites all absolute URLs in Location
headers back into /secure-rnode/ paths, which mangles the redirect into
something like /secure-rnode/HOST/PORT/realms/..., a path that doesn't
exist and returns 404.
The fix is a RewriteRule in ood_portal.yml that catches these misdirected
requests and redirects the browser to the actual provider URL:
custom_vhost_directives:
- 'RewriteCond %{REQUEST_URI} ^/secure-rnode/[^/]+/\d+/realms/'
- 'RewriteRule ^/secure-rnode/[^/]+/\d+/(realms/.*) https://<provider-host>:<port>/$1 [R=302,L,NE]'Replace <provider-host>:<port> with your OIDC provider's address
(keycloak.example.com:8443). The pattern matches any compute node's rnode path
that contains /realms/, which is the Keycloak-specific path prefix. If your
provider uses a different path structure, adjust the RewriteCond and capture
group accordingly.
This rule lives at the vhost level, outside any LocationMatch, so it fires
before OOD's rnode handler tries to proxy the request to a compute node.
In view.html.erb, set:
auth_method = "oidc"
oidc_provider = "<provider>"
The oidc_provider value must match the section name in ThinLinc's
webaccess.hconf (like "keycloak" from the example above).