Skip to content

Kerberos single sign-on

People signed in to your Windows domain open Easy8 without a login form. Your web server does the Kerberos part and passes the user name to Easy8 in an HTTP header; Easy8 signs in the user with that login.

How it works

  1. A person who is not signed in opens Easy8. Easy8 redirects the browser to /sso_autologin.
  2. The web server in front of Easy8 authenticates the person with Kerberos on /sso_autologin and adds the user name to the request as an HTTP header.
  3. Easy8 reads the header and takes the part before @ as the login: [email protected] becomes jdoe.
  4. Easy8 signs in the user with that login and returns the person to the page they opened. Users with two-factor authentication still enter their code.

If no user has that login, Easy8 creates one from an LDAP authentication source that has On-the-fly user creation enabled (Administration › LDAP authentication). Without such a source, the sign-in fails.

Before you start

  • Easy8 runs behind a web server that terminates HTTPS, as described in the Docker guide. Apache httpd with mod_auth_gssapi is the usual choice for Kerberos. Nginx needs a third-party SPNEGO module. The older mod_auth_kerb is no longer maintained; use mod_auth_gssapi.
  • A keytab for the HTTP/ service principal of the Easy8 host name.
  • Easy8 logins that match the Windows user names, or an LDAP authentication source with On-the-fly user creation.

1. Pass the user name from the web server

Protect /sso_autologin and /sso_variables with Kerberos and send the authenticated user name to Easy8 in a header. Example for Apache httpd with mod_auth_gssapi, in the virtual host that proxies to Easy8:

RequestHeader unset X-Authenticated-User

<LocationMatch "^/sso_(autologin|variables)">
    AuthType GSSAPI
    AuthName "Easy8 sign-in"
    GssapiCredStore keytab:/etc/httpd/easy8.keytab
    GssapiLocalName On
    GssapiAllowedMech krb5
    Require valid-user
    RequestHeader set X-Authenticated-User expr=%{REMOTE_USER}
</LocationMatch>
  • GssapiLocalName On removes the realm, so the header contains jdoe. Without it the header contains [email protected]; Easy8 removes the realm itself.
  • Use dashes in the header name, not underscores. Many web servers drop headers with underscores.
  • RequestHeader unset at the virtual host level removes the header from every other request, and RequestHeader set replaces any value the browser sends. Only the web server can set the user name.
  • If Easy8 runs under a path prefix such as /easy, add it to the pattern: ^/easy/sso_(autologin|variables).
  • Protect only these two paths. Kerberos on the whole site would also challenge API clients and integrations.

Easy8 trusts this header. People must reach Easy8 only through the web server: keep the Easy8 port bound to 127.0.0.1, as in the delivered docker-compose.yml.

2. Tell Easy8 which header to read

  1. Go to Administration › Easy SSO, tab Sign-in to Easy8, card Windows sign-in (Kerberos).
  2. Turn on Enable SSO.
  3. In SSO login env variable, enter the header name the way Rails sees it: add HTTP_ in front, write it in capitals and replace dashes with underscores.
Header sent by the web server Value to enter
X-Authenticated-User HTTP_X_AUTHENTICATED_USER
X-Remote-User HTTP_X_REMOTE_USER

The field suggests REMOTE_USER. That value reaches Easy8 only when the web server runs Easy8 itself, for example with Passenger. Behind a reverse proxy, which includes every Docker installation, use the header.

3. Check the set-up

Open /sso_variables in a browser that is signed in to the domain. The page works only after you enable SSO.

Field Expected value
SSO enabled? true
ENV variable the value you entered, for example HTTP_X_AUTHENTICATED_USER
Current value the user name from the web server, for example jdoe or [email protected]
Current login jdoe
Current user in DB the user's name and ID

Then sign out and open any Easy8 page. Easy8 sends you through /sso_autologin and back, signed in.

Troubleshooting

What you see What to check
Current value on /sso_variables is empty The header did not reach Easy8. Look for it under Additional variables on the same page; every header appears there with the HTTP_ prefix. If it is missing, check the web server configuration for /sso_variables. If it is there under another name, enter that name in Easy8.
Current user in DB shows Not found No user has the login shown in Current login. Create the user, fix the login, or enable On-the-fly user creation on your LDAP authentication source.
The browser keeps being redirected to /sso_autologin Easy8 does not receive the user name. Check /sso_variables as above.
Easy8 shows "Cannot login through single sign on." The header was empty or the user was not found or is locked. Check /sso_variables.

Every request, including /sso_autologin, is in log/production.log, not in the container output. On Docker, read it with:

docker compose exec app tail -f log/production.log