In several recent episodes, we described what must be fulfilled for an application server to be able to use Kerberos authentication. So we won't be dealing with DNS records, service accounts, and keytab files, but will focus on the actual configuration of the application server.
Java Applications
For Java applications, we don't have to leave the Kerberos authentication solution to the application server, but can use the Java Authentication and Authorization Service (JAAS) library. It supports Kerberos V5 and uses the Java Generic Security Service API (Java GSS-API). Some information can be found in the official article Single Sign-on Using Kerberos in Java.
Apache Tomcat
Tomcat with the use of Kerberos SSO, or otherwise called Integrated Windows Authentication, is covered and described directly in the official documentation Tomcat 7 - Windows Authentication How-To. The native method uses JAAS and configuration in the krb5.ini and jaas.conf files, but it depends on the application, as it may handle the JAAS configuration differently. Another option is to use third-party libraries. The solution using a reverse proxy seems quite wild and unnecessary to me.
Apache HTTP Server
On Apache, we have probably the only functional and widely used option, which is the Kerberos Module for Apache called mod_auth_kerb. The problem is that it is generally available only for Linux distributions (although we have the source code). Its last update was several years ago, but that doesn't matter because everything works.
For Windows, I found several different modules, such as Apache 2.0 module mod_auth_sspi, but they are mostly old and not very widely used. A closer look also reveals that they all only support NTLM SSP. These include mod_authn_ntlm, mod_auth_sspi, mod_ntlm_winbind, mod_auth_ntlm_winbind, mod_auth_ntlm.
mod_auth_kerb Module
Let's take a quick look at the use of the Apache 2.2 server with the mod_auth_kerb authentication module. We want to run the method called Integrated Windows Authentication, which means Kerberos and SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) or, in other words, Negotiate. The steps we need to take to get the module up and running are:
- Install the
mod_auth_kerbmodule, according to your Linux distribution, for example on Red Hat:
yum install mod_auth_kerb - During the installation, the loading in the Apache configuration should be set up, but if not, we can do it manually in the
httpd.conffile (of course with the correct path)
LoadModule auth_kerb_module modules/mod_auth_kerb.so - Upload the keytab file (which we prepared for the web server's DNS name) to a secure folder on the server (where the user under which Apache runs has access)
- In the Apache configuration file, configure the folder where we want to use Kerberos authentication (described below)
- Reload the configuration into Apache, for example
service httpd reload
When we have the keytab file, we can also set the Kerberos parameters for the operating system and use them for testing, for example. We can edit the /etc/krb5.conf configuration file and use the kinit command for testing (mentioned in the troubleshooting article).
Folder Configuration - Custom Configuration of the mod_auth_kerb Module
We can enable Kerberos authentication for the entire web, but then every access will be authenticated, which is an unnecessary additional load. Typically, the same is used as in form-based authentication to the web. One page performs the authentication (on the form it asks for a username and password, in Kerberos it goes through SSO) and thus authenticates the session. The application then monitors access to other pages. Before displaying a non-public page, it checks if the session is authenticated and if it has the necessary permissions. If not, it redirects to the login page or displays an error.
On the Apache server, authentication (if not handled directly by the application) is configured for a folder. We can therefore choose a folder where we will place a script that will handle the authentication, and set Kerberos authentication as required for that folder. The configuration is done in the main configuration file (usually httpd.conf) or the .htaccess file in the given web folder (which must be allowed). General information can be found in the documentation Authentication and Authorization.
Configuration is most often done in the <Directory> section, but you can also use <Location>. Example configuration:
<Directory /var/www/intranet/sso/> AuthType Kerberos KrbAuthRealms FIRMA.LOCAL KrbServiceName HTTP/www.firma.local@FIRMA.LOCAL Krb5KeyTab /etc/httpd/intranet.keytab KrbMethodNegotiate on KrbMethodK5Passwd off Require valid-user </Directory>
Several directives are used to set up the authentication:
AuthType- selects the authentication method to be used, in our caseKerberosAuthName- defines the Realm (but it's not the Kerberos Realm), which is information for the client about where they are actually connecting (displayed in the login window). It is used for Basic authentication. Kerberos (Negotiate) performs SSO, so this information is unnecessary (no window is displayed) and in practice the configuration works without this directive (according to the Apache documentation it is, however, mandatory).Require- performs authorization (who has access to the page/folder), we can list users or groups here, or use the keywordvalid-user, so all authenticated users have access (we handle authorization in the application, which is a common practice)KrbAuthRealms- defines the Kerberos Realm, it may not be necessaryKrbServiceName- the name of the service (Service Principal Name including the Realm) to be used for authentication, must be exactly the same in the keytab file (used to select the correct key from the keytab)Krb5KeyTab- specifies the Kerberos V5 keytab file to be usedKrbMethodNegotiate- explicit enabling (on) of the Kerberos protocol (Negotiate method), it is enabled by defaultKrbMethodK5Passwd- disabling (off) password authentication (Basic), themod_auth_kerbmodule by default supports the Negotiate and Basic methods, but we usually don't want the Basic method, it is enabled by defaultKrbSaveCredentials- enables (on) saving tickets to the cache, which is required for some applications
Note: Most Kerberos parameter values can be taken from the system settings if they are not defined in the configuration.
In general, it is recommended, for greater security, to send any authentication credentials only over an encrypted channel. Therefore, we can also add the directive:
SSLRequireSSL- allows access to the given folder only via TLS/SSL (i.e. HTTPS)
As we mentioned, the mod_auth_kerb module performs the default Negotiate (Kerberos) and Basic authentication. So in the header it sends
HTTP/1.1 401 Authorization Required WWW-Authenticate: Negotiate WWW-Authenticate: Basic Realm="what we set in AuthName"
If we disable the Basic authentication directive, the Apache error message will be displayed immediately upon Kerberos SSO failure. Internet Explorer will offer a login dialog (almost the same as for Basic authentication) and try to obtain a Kerberos ticket (it will use the entered credentials to authenticate on the KDC).
Using Kerberos Authentication in PHP
We set Kerberos authentication on a certain folder, as described in the previous chapter. We place a PHP script in this folder. If we now try to access this page, the web browser will attempt to perform SSO login. If something fails (for example, we don't have the browser set up or we're not logged into the domain), an error will be displayed. The PHP page will only be called if the verification was successful.
In the page code, we can therefore assume that we have a successfully authenticated user. When the Apache module performed the verification, it obtained the user's name (including the domain, for example bouska@FIRMA.LOCAL) from the Service Ticket and stored it in the server variable REMOTE_USER. As interesting, we can also find the variables PHP_AUTH_USER and AUTH_TYPE. The PHP page can contain only one command to print all server variables:
<?php print_r($_SERVER); ?>
A somewhat more meaningful script can be /sso/login.php (we set authentication on the sso folder). We'll use the session to keep the variables, and store the user's name. Then we'll redirect to the main page of the site, where we'll be logged in. Of course, we would still need to verify that the logged-in user exists on our site and perhaps load their other data from the DB.
<?php
session_start();
$_SESSION['username'] = $_SERVER['REMOTE_USER'];
header('Location: /');
?>
In practice, it is a common situation where we don't want the client who doesn't support Kerberos to get a server error message, but instead have the option to log in to the application using a form (form-based authentication). One solution is to send the client a header that we require authentication and check if the response comes with the header. The client sends the Authorization: Negotiate header only if it can perform Kerberos authentication. So if the header contains this part, we then redirect the client to the page where authentication is set up using the mod_auth_kerb module. Otherwise, we display the login form.
<?php
session_start();
$headers = apache_request_headers();
if(empty($headers['Authorization'])) {
header("HTTP/1.1 401 Authorization Required");
header("WWW-Authenticate: Negotiate");
// SSO is not supported, I'll show a standard login or information
echo "SSO authentication did not succeed.";
exit;
} else {
// SSO OK, I'll redirect to the SSO login
header('Location: /sso/login.php');
exit;
}
?>
There are no comments yet.