Most Tomcat users begin by implement Form-based authentication. Those deploying applications into enterprises soon discover that those enterprises use an Active Directory and have single sign-on on all intranet sites. They eventually find Waffle, but don’t want to take the ability to do form-based logon away.
How do we give users a way to logon either way?
You can accomplish this with the Waffle MixedAuthenticator.
Configure Tomcat
Download and Copy Files
Download Waffle 1.3 and copy waffle-jna.jar, jna.jar and platform.jar to Tomcat’s lib directory.
Configure Mixed Authenticator Valve
Add a valve and a realm to the application context. For an application, modify META-INF\context.xml.
Security Roles and Constraints
Configure security roles in WEB-INF\web.xml. The Waffle Mixed Authenticator adds all user’s security groups (including nested and domain groups) as roles during authentication.
Restrict access to website resources.
Add a second security constraint that leaves the login page unprotected.
Configure Form Login
Configure Form Login parameters with the location of the login page (repeated from the security constraint above) and an error page for failed logins. Modify WEB-INF\web.xml.
Login Page
Create a login page based on the following code. There’re two requirements for the login form. The form-based authentication must post to any valid location with the j_security_check parameter. The destination page will be loaded after a successful login. The single sign-on form must similarly post to any valid location with the j_negotiate_check parameter in the query string.
Here’s a rudimentary example that lands an authenticated user on index.jsp.
Demo
A demo application can be found in the Waffle distribution in the Samples\Tomcat\waffle-mixed directory. Copy the entire directory into Tomcat’s webapps directory and navigate to https://localhost:8080/waffle-mixed. Pick your method of login.
How does it Work?
Implementation details follow. Read at your own risk.
From the unauthenticated login page we are making two possible requests: one will trigger Single Sign-On and another will trigger form-based authentication. To do single sign-on we will need access to the request/response objects and to do forms authentication we will need access to the realms interface. The place where we have both is in org.apache.catalina.Authenticator.
Negotiate mimics the behavior of NegotiateAuthenticator, while form post follows the standard Authenticator registration process.