· 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:
| Placeholder | Meaning |
|---|---|
EXAMPLE.COM | your Kerberos realm, i.e. your AD domain name in capitals |
example.com | your DNS domain |
dc1.example.com | a domain controller (Windows Server 2016 to 2025) |
web.example.com | the web server's name as it appears in the browser's address bar |
svc-web | the 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.comis 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 package | To |
|---|---|
bin\*.dll | C:\Apache24\bin\ |
bin\plugins | C:\Apache24\bin\plugins |
modules\mod_auth_kerb.so | C:\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:debuginhttpd.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.
