Kerberos/SPNEGO sign-in with Active Directory
Configure Fortified ID Access for browser Kerberos/SPNEGO sign-in against Active Directory.
Kerberos/SPNEGO sign-in with Active Directory
Section titled “Kerberos/SPNEGO sign-in with Active Directory”This use case configures Fortified ID Access to accept Kerberos tickets from domain-joined browsers. It uses an Active Directory service account, an HTTP service principal name (SPN), and a keytab that Access reads through the Java GSS-API.
Scenario
Section titled “Scenario”Users open Access at a public hostname such as https://idp.example.com. A domain-joined browser obtains a ticket for HTTP/[email protected] and presents it to the KerberosAuthentication authenticator. Access validates the ticket and maps the authenticated principal to its short username.
This use case builds on the Kerberos/SPNEGO authenticator reference. Use the reference for browser policy, proxy, load-balancing, and fallback-flow requirements.
Prerequisite
Section titled “Prerequisite”- An Active Directory administrator can create or manage a dedicated service account and register an SPN.
- The public hostname resolves to Access and is the hostname that users enter in their browser.
- Each Access node can resolve and reach the KDC, has synchronized time, and can read its local copy of the keytab.
- The browser is configured to allow integrated authentication to the public hostname.
- The Access build includes the Kerberos login view described in the authenticator reference.
Configuration
Section titled “Configuration”Complete the configuration in this order:
- Create a dedicated AD service account and register its HTTP SPN.
- Generate the keytab and store it outside any configuration Git working tree.
- Configure
jaas.conf,krb5.conf, and the Access Java options. - Place the configuration files and keytab with the required protection.
- Configure
KerberosAuthenticationin the AuthN module. - Add the Kerberos option to a Selector and restrict it to the intended client network.
Step 1: Create the service identity and SPN
Section titled “Step 1: Create the service identity and SPN”Create a dedicated AD service account, for example EXAMPLE\access-kerberos.
Register the HTTP SPN for the public browser hostname. Use setspn -S, which checks for duplicate SPNs:
setspn -S HTTP/idp.example.com EXAMPLE\access-kerberosVerify that the SPN resolves to the intended account before generating the keytab:
setspn -Q HTTP/idp.example.comThe SPN, the keytab principal, the JAAS principal, and Access service_principal must all name the same HTTP service. The service class stays HTTP when users access the service over HTTPS.
Step 2: Generate and protect the keytab
Section titled “Step 2: Generate and protect the keytab”Generate a keytab for HTTP/[email protected], mapped to the dedicated service account, using the organization's approved Active Directory procedure. The example environment used AES256-SHA1 and KRB5_NT_PRINCIPAL.
On an AD administration workstation, run the following command in PowerShell to generate the keytab:
ktpass /out C:\secure-output\http.keytab ` /princ HTTP/[email protected] ` /mapuser EXAMPLE\access-kerberos ` /pass * ` /crypto AES256-SHA1 ` /ptype KRB5_NT_PRINCIPALConfirm that the command maps the expected principal and writes the keytab, then transfer it through an approved secure channel to each Access node. Do not copy the key value that ktpass can print into logs, tickets, or documentation.
For Linux Access nodes, run ktpass on a Windows-based AD administration workstation and securely distribute the generated http.keytab to each node.
Do not place a service-account password in a shared command line, Access configuration, source control, or this documentation. Store the generated http.keytab outside source control, deploy it to every Access node, and restrict it to the Access service account. See the ktpass reference for the required mapping and export options.
Step 3: Configure JAAS and the Kerberos realm
Section titled “Step 3: Configure JAAS and the Kerberos realm”Create jaas.conf in a protected Access configuration directory. Replace the example principal and keytab location with the values for the environment. Use forward slashes in the keytab path; Java accepts them on both Windows and Linux.
AccessKerberos { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true keyTab="<protected keytab path>/http.keytab" storeKey=true doNotPrompt=true isInitiator=false;};Create krb5.conf with the Kerberos realm and KDC used by Access:
[libdefaults] default_realm = EXAMPLE.COM
[realms] EXAMPLE.COM = { kdc = dc01.example.com kdc = dc02.example.com }Add the following Java options to the Access service, replacing <installation path> with the Access installation directory:
-Djava.security.auth.login.config=<installation path>\mgmt-center\data\customer\access\jaas.conf-Djava.security.krb5.conf=<installation path>\mgmt-center\data\customer\access\krb5.confRestart the Access service after changing its Java options or either configuration file.
Step 4: Place the configuration files
Section titled “Step 4: Place the configuration files”Keep jaas.conf and krb5.conf with the Access customer configuration on each Access node:
<installation path>/mgmt-center/data/customer/access/├── jaas.conf├── krb5.confStore http.keytab in a protected directory outside any Access configuration Git working tree, and use its absolute path in jaas.conf. The keytab contains the service account's Kerberos key material. When Access runs as Local System, grant NT AUTHORITY\\SYSTEM read access and prevent ordinary users from reading or changing the file. Local administrators remain trusted administrators of the server.
The jaas.conf and krb5.conf files do not normally contain a password or key, but keep them under controlled configuration permissions because they identify the service principal, keytab location, realm, and KDCs. If the Access configuration directory is a Git working tree, do not add the keytab to it. If an operational requirement makes that unavoidable, ignore http.keytab in that repository before copying it there; .gitignore prevents an accidental add but does not provide access control or remove a file that Git already tracks.
Step 5: Configure the authenticator
Section titled “Step 5: Configure the authenticator”Add the Kerberos authenticator to the AuthN module. This example uses the existing ${globals.default_login_suffix} path, accepts only EXAMPLE.COM, and maps [email protected] to alice.
{ "id": "kerberosauthentication_1", "type": "KerberosAuthentication", "description": "Cross-platform Kerberos/SPNEGO authentication using Java GSS-API.", "config": { "base_path": "${globals.default_login_suffix}", "jaas_context": "AccessKerberos", "username_mapping": "short_name", "allowed_realms": ["EXAMPLE.COM"], "on_probe_unavailable": "cancel" }, "display_name": "Kerberos / SPNEGO"}Use short_name only when usernames are unique across all accepted realms. Use the default principal mapping when retaining the realm is necessary to keep user identities distinct.
Step 6: Present Kerberos through a Selector
Section titled “Step 6: Present Kerberos through a Selector”In this example, the Selector routes the user to kerberosauthentication_1. The Selector contains only the Kerberos option:
{ "id": "select", "type": "Selector", "display_name": "Selector", "description": "Selector", "config": { "base_path": "${globals.default_login_suffix}", "overlay_dir": "${globals.default_overlay_dir}", "webroot_dir": "web/authenticator/selector", "options": [ { "id": "kerberos", "target": "kerberosauthentication_1", "order": 1, "label": "Kerberos / SPNEGO 1", "include_expr": "ipv4.isInSubnet(request.remote_address, '192.168.10.0/24')" } ] }}The include_expr makes the Kerberos option available only when Access sees the client address in 192.168.10.0/24. Since this example has no other option, clients outside that subnet cannot select an authentication method from this Selector. When Access is behind a reverse proxy or load balancer, ensure that request.remote_address represents the original client address before relying on this filter. See Selector option filtering and the ipv4.isInSubnet expression for the predicate syntax.
Test the configuration
Section titled “Test the configuration”-
Query the SPN with
setspn -Q HTTP/idp.example.comand confirm that it belongs to the dedicated service account. -
On each Access node, use
klist -k -e <keytab path>to verify that the deployed keytab containsHTTP/[email protected]. Do not useklist -K, because it prints key values. -
From a domain-joined Windows test client, signed in as the test user, request a service ticket and inspect the ticket cache:
Terminal window klist get HTTP/idp.example.comklist ticketsThe commands should complete without an error and
klist ticketsshould show a cached service ticket forHTTP/idp.example.com. This verifies that Active Directory can find the SPN and that the domain controller can issue a service ticket for it. It does not verify that Access can read or usehttp.keytab; that is verified in step 2 and by the browser test. -
Open the configured Access login path in a browser that is allowed to use integrated authentication for
idp.example.com. For example, navigate to a service provider (SP) or relying party (RP) that is protected by this sign-in method and initiate its sign-in flow. -
Confirm that Access completes the Kerberos step, continues the configured Chain, and records successful authentication as CEF event
WEB_100015. -
Test a client without a usable ticket and confirm the configured
on_probe_unavailablebehavior. When usingcancel, also test that the Selector or other fallback path is usable. -
Optional — when using the Selector filter in this example: Test a client from
192.168.10.0/24and confirm that the Selector presents the Kerberos option. Test a client outside that subnet and confirm that the option is absent.
Adjust configuration for production
Section titled “Adjust configuration for production”- Use a dedicated, least-privileged AD service account and document its ownership and keytab-rotation procedure.
- Replace the keytab on every Access node whenever the service-account key changes. Keep the key version and encryption type aligned with Active Directory.
- When Access is behind a reverse proxy or load balancer, preserve the
AuthorizationandWWW-Authenticateheaders, preserve the Access session cookie, and keep a multi-step GSS exchange on one Access node. - Test the exact public hostname, browser version, operating system, and effective browser policy used in production.
Troubleshooting
Section titled “Troubleshooting”If the browser repeatedly receives 401 after sending a ticket, first compare the public hostname, SPN, keytab principal, JAAS principal, and service_principal. Then check the keytab version and encryption type, DNS and KDC reachability, clock synchronization, browser policy, and reverse-proxy headers. Do not log Negotiate tokens or keytab contents.
For additional diagnostic guidance, see Kerberos/SPNEGO troubleshooting.