Single Sign-On: Tomcat Negotiate Authenticator (Kerberos + NTLM) w/ Waffle

Back | tomcat, waffle, java, active directory | 5/20/2010 |

image

I’ve added a Tomcat Negotiate (Kerberos + NTLM) authenticator to Waffle 1.3 for Tomcat 6. Here’s how to use it.

Download

Download Waffle 1.3. The zip contains Waffle.chm that has the latest version of this tutorial.

Configure Tomcat

Copy Files

I started with a default installation of Tomcat 6. Checked that I could start the server and navigate to http://localhost:8080. Copy the following files into tomcat’s lib directory.

  • jna.jar: Java Native Access
  • platform.jar: JNA platform-specific API
  • waffle-jna.jar: Tomcat Negotiate Authenticator

Authenticator Valve

Add a valve and a realm to the application context in your context.xml (for an application) or in server.xml (for the entire Tomcat installation).

  1. <Context>
  2.   <Valve className="waffle.apache.NegotiateAuthenticator" principalFormat="fqn" roleFormat="both" />
  3.   <Realm className="waffle.apache.WindowsRealm" />
  4. </Context>

Security Roles

Configure security roles in your application’s web.xml. The Waffle authenticator adds all user's security groups (including nested and domain groups) as roles during authentication.

  1. <security-role>
  2.   <role-name>Everyone</role-name>
  3. </security-role>

Restrict Access

Restrict access to website resources. For example, to restrict the entire website to locally authenticated users add the following in web.xml.

  1. <security-constraint>
  2.   <display-name>Waffle Security Constraint</display-name>
  3.   <web-resource-collection>
  4.     <web-resource-name>Protected Area</web-resource-name>
  5.     <url-pattern>/*</url-pattern>
  6.   </web-resource-collection>
  7.   <auth-constraint>
  8.     <role-name>Everyone</role-name>
  9.   </auth-constraint>
  10. </security-constraint>

Test

Restart Tomcat and navigate to http://localhost:8080/.

You should be prompted for a logon with a popup. This is because by default localhost is not in the Intranet Zone and the server returned a 401 Unauthorized. Internet servers with a fully qualified named are detected automatically.

Internet Explorer

Ensure that Integrated Windows Authentication is enabled.

  1. Choose the Tools, Internet Options menu.
  2. Click the Advanced tab.
  3. Scroll down to Security
  4. Check Enable Integrated Windows Authentication.
  5. Restart the browser.

The target website must be in the Intranet Zone.

  1. Navigate to the website.
  2. Choose the Tools, Internet Options menu.
  3. Click the Local Intranet icon.
  4. Click the Sites button.
  5. Check Autmatically detect intranet network.
  6. For localhost, click Advanced.
  7. Add http://localhost to the list.

Firefox

    1. Type about:config in the address bar and hit enter.
    2. Type network.negotiate-auth.trusted-uris in the Filter box.
    3. Put your server name as the value. If you have more than one server, you can enter them all as a comma separated list.
    4. Close the tab.

Navigate to http://localhost:8080 after adding it to the Intranet Zone.

image

You should no longer be prompted and automatically authenticated.

image

Logs

In the logs you will see the following output for a successful logon.

  1. FINE: logged in user: dblock-green\dblock (S-1-5-21-3442045183-1395134217-4167419351-1000)
  2. FINE:  group: dblock-green\None
  3. FINE:  group: Everyone
  4. FINE:  group: dblock-green\HelpLibraryUpdaters
  5. FINE:  group: dblock-green\HomeUsers
  6. FINE:  group: BUILTIN\Administrators
  7. FINE:  group: BUILTIN\Users
  8. FINE:  group: NT AUTHORITY\INTERACTIVE
  9. FINE:  group: CONSOLE LOGON
  10. FINE:  group: NT AUTHORITY\Authenticated Users
  11. FINE:  group: NT AUTHORITY\This Organization
  12. FINE:  group: S-1-5-5-0-442419
  13. FINE:  group: LOCAL
  14. FINE:  group: NT AUTHORITY\NTLM Authentication
  15. FINE:  group: Mandatory Label\Medium Mandatory Level
  16. INFO: successfully logged in user: dblock-green\dblock

My laptop is not a member of an Active Directory domain, but you would see domain groups, including nested ones here. There’s nothing special to do for Active Directory. The authenticator also automatically handles all aspects of the Negotiate protocol, chooses Kerberos vs. NTLM and supports NTLM POST. It basically has the same effect in Tomcat as choosing Integrated Windows authentication options in IIS.

Links

Related Projects

  • Tomcat SPNEGO by Dominique Guerrin: this is a very good prototype of a filter. It uses JNI and not JNA, doesn’t support NTLM POST and the code is pretty thick.
  • SPNEGO Sourceforge: it’s a nightmare to configure, doesn’t work without an Active Directory domain and requires an SPN
  • JCIFS NTLM: no longer supported and they recommend using Jespa
  • Jespa: a commercial implementation that claims to do the same thing as Waffle, but uses the Netlogon service instead of the native Windows API
Hello, I am trying to use automatic authentication between tomcat 6 and IE.

Tomcat is running in my machine, and my machine is in the company AD.



When I run the sample waffle-negotiate (http://localhost:8080/waffle-negotiate/) the lines bellow apears in the log file and the browser does not show the information about logged user.



23/11/2010 10:46:18 org.apache.catalina.startup.Catalina start

INFO: Server startup in 1627 ms

23/11/2010 10:48:16 waffle.apache.NegotiateAuthenticator authenticate

BOM: GET /waffle-negotiate/, contentlength: -1

23/11/2010 10:48:16 waffle.apache.NegotiateAuthenticator authenticate

BOM: authorization: <none>, ntlm post: false

23/11/2010 10:48:16 waffle.apache.NegotiateAuthenticator authenticate

BOM: authorization required



Could you help me?



Regards
Azize @ Tuesday, 23 November 2010 Reply
Please ask questions in Waffle Discussions area.
dB. @ Tuesday, 23 November 2010 Reply
Hi, I wonder if it is possible to put the role created in activedirectory as a dynamic value in the context or init param, so I can get role or user in the application, at the moment, my CLIENT_INFO_USER is null, I wonder why is that.


deejaymore @ Wednesday, 17 November 2010 Reply
You should ask this question on Waffle discussions with a bit more detail.
dB. @ Wednesday, 17 November 2010 Reply
Hi there,



I installed the waffle samples as you have discribed. The waffle jar files are written to tomcat lib directory. The waffle-filter example is working fine but the waffle-negotiate example (in which i'm interested) is not working it returns a blank page. I'm using tomcat version 6.0 on a windows 2003 machine. Any idea what could be the problem? Let me know if you need more information to investigate the problem.



Thanks in advance,



Rob
Rob de Veij @ Thursday, 19 August 2010 Reply
Post server logs and client-server HTTP trace to the Waffle Discussions.
dB. @ Friday, 20 August 2010 Reply