SSO to AD domain

CzechIdM supports Single-Sign-On of the AD domain users. The mechanism uses web server, which handles the Kerberos authentication and provides the login of the authenticated user in the HTTP header. Then CzechIdM processes this header and authenticates the user automatically.

If the user is the Application Admin (e.g. has assigned the role superAdminRole), SSO authentication is disabled for security reasons.

This tutorial shows how to configure an Apache web server and enable SSO in CzechIdM.

When enabling SSO, be sure that your Apache Tomcat application server listens only on localhost (as in standard configuration by install guide), so no one can forge the HTTP headers and gain access pretending to be one of the users.

During the tutorial, we use the name of the AD domain COMPANY.CZ. CzechIdM will be accessible from the address https://idm.company.

A new service for CzechIdM must be configured in AD. The service must be linked to a specific user. We recommend using only one user per one service (linking multiple services to one user is theoretically possible, but linking one service to multiple users breaks the Kerberos authentication).

Create a new AD user (no special privileges required), e.g. "idm-sso".

Choose the name of the service: HTTP/idm.company@COMPANY.CZ (this doesn't have to contain the exact name of the IdM server, but it helps).

In AD domain controller, start the CMD and generate the keytab:

ktpass -out idm.company.keytab -princ HTTP/idm.company@COMPANY.CZ -mapUser idm-sso@company.cz -crypto all -pass * -ptype KRB5_NT_PRINCIPAL 

The command will prompt for a password.

Download the generated file idm.company.keytab, which will be used in the next steps.

We expect that Apache is installed according to the admin guide.

Install mod_auth_kerb:

yum install mod_auth_kerb

Put the file idm.company.keytab in /etc/httpd/keytabs/ and set correct permissions:

mkdir /etc/httpd/keytabs/
chmod 755 /etc/httpd/keytabs/
mv idm.company.keytab /etc/httpd/keytabs/idm.company.keytab
chown apache:apache /etc/httpd/keytabs/idm.company.keytab
chmod 600 /etc/httpd/keytabs/idm.company.keytab

Configure Kerberos realm in /etc/krb5.conf and the addresses of the domain controllers. We use DC dc.company.cz in our example:

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 default_realm = COMPANY.CZ
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true

[realms]
 COMPANY.CZ = {
  kdc = dc.company.cz
  admin_server = dc.company.cz
 }

[domain_realm]
 .company.cz = COMPANY.CZ
 company.cz = COMPANY.CZ

Check that the keytab works:

yum install krb5-workstation
kinit -k -t /etc/httpd/keytabs/idm.company.keytab HTTP/idm.company@COMPANY.CZ
klist -e

Edit proxy settings in the /etc/httpd/conf.d/ssl.conf

change this:
ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/

to this:
ProxyPass /idm/ ajp://localhost:8009/idm/
ProxyPassReverse /idm/ ajp://localhost:8009/idm/

Add Kerberos configuration and setting the REMOTE_USER header inside the VirtualHost tag in /etc/httpd/conf.d/ssl.conf:

       <Location /idm>
            AuthName "Kerberos Login"
            AuthType Kerberos
            KrbMethodNegotiate On
            KrbMethodK5Passwd On
            KrbAuthRealms COMPANY.CZ
            KrbServiceName HTTP/idm.company@COMPANY.CZ
            Krb5KeyTab /etc/httpd/keytabs/idm.company.keytab
            require valid-user
        </Location>

       RequestHeader set REMOTE_USER %{REMOTE_USER}s

This configuration enables Negotiate (the users logged in domain computer will be automatically authenticated - this must be enabled in the browser), as well as Basic Auth (the user, who is not logged in domain computer, will be first prompted for username and password with the message "Kerberos Login" and the credentials will be sent to AD for authentication). Negotiate can be disabled by KrbMethodNegotiate, Basic Auth can be disabled by KrbMethodK5Passwd.

Restart httpd service:

systemctl restart httpd

Sending of Kerberos tickets (the method Negotiate) must be enabled in the browsers, otherwise the automatic authentication wouldn't work.

Internet Explorer:

  • Internet Options - Security - Trusted Sites - add https://idm.company
  • FIXME is this necessary as well?: Internet Options - Security - Local Intranet Zone - Custom - User Authentication - Logon - Automatic logon with current user name and password
  • IE setup for Automatic logon:

Internet Explorer doesn't support Negotiate, if the address is IP address. If the server name isn't in DNS, you can add it to C:\Windows\System32\drivers\etc\hosts (for testing purposes).

Mozilla Firefox:

For more information about browsers see https://www.samuraj-cz.com/clanek/kerberos-cast-10-nastaveni-webovych-prohlizecu/

SSO must be enabled in IdM configuration. Set the following to the application-SOMEPROFILE.properties:

idm.sec.core.authentication-filter.core-sso-authentication-filter.enabled=true
idm.sec.core.authentication-filter.core-sso-authentication-filter.header-name=REMOTE_USER
idm.sec.core.authentication-filter.core-sso-authentication-filter.uid-suffixes=@COMPANY.CZ

All configuration properties for SSO are described here: SSO configuration properties.

Although the SSO can be configured in the GUI (in configuration properties), we strongly discourage it. In case of broken GUI/authentication, you will have no other means to disable the SSO functionality than manually editing contents of the identity manager's database
Users with superAdminRole cannot login by SSO, they will still be asked for password. This is by design.

General things to check:

  • The service principal name must be linked only to one user in AD.
  • The keytab shouldn't be generated with only some ciphers, so use -crypto all in the command as above.

Usual messages in Apache error log:

  • krb5_get_init_creds_password() failed: Cannot contact any KDC for requested realm: make sure that DC in /etc/krb5.conf kdc communicates on port 88:
telnet dc.company.cz 88
  • krb5_get_init_creds_password() failed: Client not found in Kerberos database: the given user doesn't exist in AD (nothing wrong with configuration)
  • krb5_get_init_creds_password() failed: Preauthentication failed: the given user has different password.
  • gss_accept_sec_context() failed: No credentials were supplied, or the credentials were unavailable or inaccessible (, Unknown error): the client doesn't trust the address of IdM, i.e. it isn't in Trusted sites in Internet Explorer.
  • failed to verify krb5 credentials: Key table entry not found: something is wrong with the keytab. Try to compare its version (KVNO) and the version of Kerberos ticket:
$ klist -k /etc/httpd/keytabs/idm.company.keytab 
Keytab name: FILE:/etc/httpd/keytabs/idm.company.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   5 HTTP/idm.company@COMPANY.CZ
   5 HTTP/idm.company@COMPANY.CZ
   5 HTTP/idm.company@COMPANY.CZ
   5 HTTP/idm.company@COMPANY.CZ
   5 HTTP/idm.company@COMPANY.CZ

$ kinit -k -t /etc/httpd/keytabs/idm.company.keytab HTTP/idm.company@COMPANY.CZ
$ kvno HTTP/idm.company@COMPANY.CZ
HTTP/idm.company@COMPANY.CZ: kvno = 5
  • krb5_rd_req() failed when verifying KDC followed by failed to verify krb5 credentials: Permission denied: Bad permissions on the keytab file. All httpd processes must have read access to the keytab.