Schäuffelhut Berger – Software Engineering
DE|EN

← All posts

· Matthias C. Berger

Single sign-on with Apache on Windows: a guide for Windows Server 2022 and 2025

Your users are logged on to their Windows machines in the domain, and the web application on your Apache should recognise them without asking for another password. On Linux, the mod_auth_kerb module does this. There is no ready-made Kerberos module for Apache on Windows, so we ported it: mod_auth_kerb for Windows.

This guide shows the setup with the current version 2.0 on Windows Server 2022 or 2025, with Apache 2.4 from Apache Lounge. It replaces our 2014 guide for Apache 2.2. Version 2.0 will be released in mid-November 2026.

The environment

The examples use placeholders; replace them with your own names:

PlaceholderMeaning
EXAMPLE.COMyour Kerberos realm, i.e. your AD domain name in capitals
example.comyour DNS domain
dc1.example.coma domain controller (Windows Server 2016 to 2025)
web.example.comthe web server's name as it appears in the browser's address bar
svc-webthe service account for the web server

The web server needs access to the domain controller (port 88), and its clock must be within five minutes of the domain controller's.

1. Create a service account in Active Directory

Create a user account in Active Directory for the web server, for example svc-web:

  • Enable "Password never expires", disable "User must change password at next logon".
  • On the "Account" tab, enable "This account supports Kerberos AES 256 bit encryption".
  • Only if the application should work on with the users' tickets (KrbSaveCredentials, see below): on the "Delegation" tab, trust the account for delegation.

2. Create the keytab

The keytab holds the key Apache uses to check the browsers' Kerberos tickets. Create it on a domain controller as a domain administrator:

ktpass /out krb5.keytab ^
       /princ HTTP/web.example.com@EXAMPLE.COM ^
       /mapuser EXAMPLE\svc-web ^
       /pass * ^
       /crypto AES256-SHA1 ^
       /ptype KRB5_NT_PRINCIPAL
  • web.example.com is the name users type into the browser to reach the server. If it doesn't match the principal, there is no single sign-on.
  • /pass * prompts for the password instead of putting it on the command line.
  • Use AES, not RC4 as in older guides.

Treat the keytab like a password. Only administrators and the account Apache runs as (LocalSystem by default) should be able to read it.

3. Install Apache and the module

Requirements on the web server:

  • Apache httpd 2.4 x64 from Apache Lounge, VS18 build
  • the latest Visual C++ Redistributable (x64), as required by Apache Lounge

The examples assume Apache in C:\Apache24. Copy from the mod_auth_kerb 2.0 package:

From the packageTo
bin\*.dllC:\Apache24\bin\
bin\pluginsC:\Apache24\bin\plugins
modules\mod_auth_kerb.soC:\Apache24\modules\

The Kerberos libraries (MIT Kerberos 1.22) now sit next to httpd.exe. A separate "MIT Kerberos for Windows" installation is not needed. If you are coming from version 1.x: uninstall KfW, restart the server, then copy the files. httpd.conf, krb5.ini and the keytab stay as they are.

Copy the keytab from step 2 to C:\Apache24\conf\krb5.keytab.

4. Configure Kerberos

The Kerberos configuration lives in C:\ProgramData\MIT\Kerberos5\krb5.ini (C:\ProgramData is hidden, but it exists):

[libdefaults]
    default_realm = EXAMPLE.COM
    dns_lookup_kdc = true
    rdns = false

[realms]
    EXAMPLE.COM = {
        kdc = dc1.example.com
    }

[domain_realm]
    .example.com = EXAMPLE.COM

5. Configure Apache

In C:\Apache24\conf\httpd.conf:

LoadModule auth_kerb_module modules/mod_auth_kerb.so

<Location /secure>
    AuthType Kerberos
    AuthName "Login"
    KrbMethodNegotiate On
    KrbMethodK5Passwd On
    KrbAuthRealms EXAMPLE.COM
    Krb5Keytab conf/krb5.keytab
    KrbServiceName Any
    Require valid-user
</Location>
  • KrbMethodNegotiate On: single sign-on for users logged on to the domain.
  • KrbMethodK5Passwd On: anyone without a ticket (a Mac outside the domain, say, or a script) can log in with user name and password, which the module checks against the domain controller. Use this only over HTTPS: with Basic authentication the password crosses the wire unencrypted.
  • KrbServiceName Any: Apache accepts every key in the keytab.

Check and start:

C:\Apache24\bin\httpd.exe -t
net start Apache2.4

The Apache error log then shows mod_auth_kerb/5.4-sbg2.0 in the version line.

6. Test

A test page C:\Apache24\htdocs\secure\index.php (with PHP) shows who is logged in:

<?php echo "Logged in as: ", htmlspecialchars($_SERVER["REMOTE_USER"]); ?>

Without PHP, any static page will do; the Apache access log then shows the logged-in user.

From a Windows machine in the domain, logged in as a domain user:

curl.exe --negotiate -u : https://web.example.com/secure/

With user name and password, from any machine:

curl.exe -u username https://web.example.com/secure/

7. Browsers

Edge and Chrome send their Kerberos ticket only to servers in the "Local intranet" zone. Add https://web.example.com there, ideally by group policy for all machines. Firefox also needs the server in network.negotiate-auth.trusted-uris.

Several domains

One Apache can log in users from several domains, even without a trust between them. Create a service account in each domain and add its key to the same keytab, on a domain controller of that domain:

ktpass /in krb5.keytab /out krb5.keytab ^
       /princ HTTP/web.example.com@OTHER.EXAMPLE ^
       /mapuser OTHER\svc-web ^
       /pass * ^
       /crypto AES256-SHA1 ^
       /ptype KRB5_NT_PRINCIPAL

Add the second realm under [realms] in krb5.ini, and set KrbAuthRealms EXAMPLE.COM OTHER.EXAMPLE in the Apache configuration. For Basic logins without @REALM, the module tries the realms in this order.

Passing tickets to the application

With KrbSaveCredentials On, the module puts the user's tickets into a ticket cache for the duration of the request. The application finds it through the KRB5CCNAME environment variable and can use it to reach further services on the user's behalf. With single sign-on, this requires the service account to be trusted for delegation (step 1). The module deletes the cache after the request.

Troubleshooting

  • Detailed log: LogLevel warn auth_kerb:debug in httpd.conf.
  • gss_acquire_cred_from() failed: the keytab is missing, unreadable, or has no key for the requested principal.
  • The browser asks for user name and password instead of single sign-on: the server is not in the "Local intranet" zone, or the name in the address bar doesn't match the HTTP/ principal in the keytab.
  • The clocks of web server and domain controller must be within five minutes of each other.

Licence and support

mod_auth_kerb 2.0 for Windows is a product of Schäuffelhut Berger GmbH. Price and licence are on the product page. We're glad to help with the setup, with several domains, or with the move from version 1.x: get in touch.