Configuring Tomcat for Windows Integrated Authentication

Before Getting Started

Be sure that you have read and successfully performed ALL of the steps in the pre-flight documentation before proceeding any further.

Finally, confirm that the server is on the domain by going to Start > Control Panel > System and opening the "System Properties" window.

We want to be sure that the host/server is on the domain. If during install of Windows Server you did not specify to join a Domain, you can click the "Change..." button now to join the Domain.

Downloading and Installing Tomcat

Go to the Apache Tomcat web site and download the "Windows Service Installer" version from the binary distribution section of the download page.

Logon to your server as Administrator and perform the installation.

By default, Tomcat will be installed under: \Program Files\Apache Software Foundation\Tomcat 6.0

Notice that the Tomcat Home directory contains the directories conf, lib, and webapps. We will be modifying the web.xml file under conf, adding spnego.jar to lib and creating a test jsp page.

Testing the Tomcat Install

Before we install and configure the SPNEGO HTTP Servlet Filter, we will first confirm that Tomcat is running and performing as expected. By default, the Tomcat service runs on port 8080. From your workstation, open IE and go to the http://medusa:8080/index.jsp web page. Obviously substitute the name of my server (medusa) for the name of your server.

Downloading spnego.jar

If your environment is the following:

  • Tomcat 8 and Java 8
  • Tomcat 9 and Java 11+

please use spnego-r9.jar

However, if your environment is the following:

  • Tomcat 10+ and Java 11+

please use spnego-jakarta-2.0.jar

You can download either of these jars from sourceforge.

Place the spnego.jar file in Tomcat's lib directory:

Modifying the web.xml file

Open the \Program Files\Apache Software Foundation\Tomcat 6.0\conf\web.xml file in a text editor.

Find the <filter> section in the file and add your servlet's initial parameter configuration.

Here's an example configuration:

<filter>
    <filter-name>SpnegoHttpFilter</filter-name>
    <filter-class>net.sourceforge.spnego.SpnegoHttpFilter</filter-class>

    <init-param>
        <param-name>spnego.allow.basic</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.allow.localhost</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.allow.unsecure.basic</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.login.client.module</param-name>
        <param-value>spnego-client</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.krb5.conf</param-name>
        <param-value>krb5.conf</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.login.conf</param-name>
        <param-value>login.conf</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.preauth.username</param-name>
        <param-value>Zeus</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.preauth.password</param-name>
        <param-value>Z3usP@55</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.login.server.module</param-name>
        <param-value>spnego-server</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.prompt.ntlm</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.logger.level</param-name>
        <param-value>1</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>SpnegoHttpFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
</filter-mapping>

Creating a krb5.conf and login.conf file

The pre-flight documentation illustrated how to create the krb5.conf and login.conf files for your environment. It also introduced you to the HelloKDC java program that makes use of these files.

Copy the krb5.conf and login.conf files that you created earlier to the Tomcat Home directory (note that the JRE must be able to find these files).

If you are running Tomcat from the command line, you may want to put these two files in the bin directory.

Registering an SPN

The best way to register an SPN is to have someone from your Admin/OPS department do it for you. Your OPS team will use the setspn.exe utility found in the Support Tools directory to register all of your SPNs. They will login as Administrator on any machine that has the Support Tools installed and run the command(s).

Your OPS team will need two things from you before running the setspn.exe utility:

  • Pre-authentication (domain) account name
  • List of all SPNs to be registered
  • The pre-authentication username should be the same one you used in pre-flight when you ran the HelloKDC.java program.

    The list of SPNs should comprise of ALL possible aliases for your service. For example, we have a server named \\MEDUSA that has an HTTP server running on port 8080; hence, we have registered these two SPNs:

    HTTP/medusa
    and
    HTTP/medusa.athena.local

    Also, we have two DNS entries that point http://intranet.kerbtek.com and http://intranet to the \\MEDUSA server; hence, we have additionally registered these two SPNs:

    HTTP/intranet
    and
    HTTP/intranet.kerbtek.com

    To register the above SPNs, someone from your OPS department would run the following commands:

    setspn.exe -A HTTP/medusa Zeus
    setspn.exe -A HTTP/medusa.athena.local Zeus
    setspn.exe -A HTTP/intranet Zeus
    setspn.exe -A HTTP/intranet.kerbtek.com Zeus

    Here are the results after running the setspn.exe utility and listing the results:

    Notice that we only needed to register service principal names for Zeus. The commands above are the ONLY commands that need to be performed.

    We do not want to pass-in as the 3rd argument anything or any name other than the pre-authentication account name.

    Again, when running the setspn.exe utility with the -A flag, the ONLY value we want for the 3rd/last argument is the pre-authentication account name.

    Furthermore, we ONLY want to register principal names with the HTTP/ prefix. We do not want to register principal names with a prefix other than HTTP/.

    Finally, be careful that you do NOT register an SPN to more than one username. A username can have more than one SPN registered but an SPN can only have one username.

    For example, the following two commands are illegal:

    prompt>setspn.exe -A HTTP/badexample Dumb
    prompt>setspn.exe -A HTTP/badexample Dumber

    The SPN HTTP/badexample cannot be resolved to a unique domain account.

    Creating the hello_spnego.jsp file

    Create the following hello_spnego.jsp file under the
    \Program Files\Apache Software Foundation\Tomcat 6.0\webapps\ROOT directory.

    <html>
    <head>
        <title>Hello SPNEGO Example</title>
    </head>
    <body>
    Hello <%= request.getRemoteUser() %> !
    </body>
    </html>
    

    Restart the server and login into a workstation before performing the test in the next section.

    Testing hello_spnego.jsp

    At this point there should at least be three hosts on your domain (athena.local):

  • 1) \\hercules (workstation)
  • 2) \\medusa (http server)
  • 3) \\cerberus (Active Directory)
  • Login into your host named \\hercules and use the ping command to confirm that all three machines are on the athena.local domain.

    Example results from ping-ing \\medusa:

    Open a browser and go to http://medusa:8080/hello_spnego.jsp

    If all is working correctly you should see the following (without being prompted):

    Lastly, the javax.servlet.http.HttpServletRequest API is an interface that defines the method named getRemoteUser. In addition, the API defines the method named isUserInRole. The SPNEGO Library also implements the isUserInRole method.

    In this guide, the SPNEGO Library was configured to perform authentication (authN). However, the SPNEGO Library defines additional APIs as well as provide a reference implementation that allow for a more expressive authorization (authZ) scheme.

    If in addition to authenticating the user, you also need to check the user's authorization credentials, take a look at the enable authZ with LDAP guide.

    The javadocs for the SpnegoAccessControl interface, the UserAccessControl interface, and the LdapAccessControl class contain authorization usage examples.

    Troubleshooting hello_spnego.jsp

    The best way to troubleshoot hello_spnego.jsp is to run TCPMon.

    Take a look at the Troubleshooting hello_spnego.jsp page for more details on using this tool.

    Links:
    pre-flight checklist
    install guide - tomcat
    install guide - jboss
    install guide - glassfish
    install guide - spring boot 2.x
    install guide - spring boot 3.x
    enable authZ with LDAP
    get user group info from LDAP
    reference docs
    api docs
    download

    Troubleshooting:
    HelloKDC.java
    hello_spnego.jsp
    HelloKeytab.java
    hello_delegate.jsp
    SpnegoHelloClient.java
    ExampleSpnegoAuthenticatorValve.java

    Examples:
    create keytab for client
    create keytab for app server
    credential delegation
    protected SOAP Web Service
    tomcat authenticator valve
    jboss authenticator valve
    authZ for standalone apps
    protecting edit button on page

    Licensing:
    GNU LGPL


    © 2009 Darwin V. Felix. All rights reserved.