Authenticate Tomcat Web Apps Against LDAP with JNDI Realm
Configure Tomcat's JNDI Realm for container-managed LDAP authentication, map roles in web.xml, and verify the flow without changing application code.
06 Aug 2025, 22:26 UTC

The problem: securing every app the same way
You have several Java web applications running on Apache Tomcat, and each one repeats the same login logic: collect credentials, connect to LDAP, bind as the user, and fetch group membership. That duplication makes security harder to audit and easier to get wrong.
Tomcat's container-managed security moves that work out of your application code. The JNDIRealm component authenticates users against an external directory such as LDAP or Active Directory, while web.xml declares which URLs require which roles. Your servlet only needs to call HttpServletRequest.login() or rely on form-based authentication. This example targets Tomcat 9.x; attribute names and defaults can differ in older major versions.
Configure JNDIRealm in server.xml
Edit $CATALINA_HOME/conf/server.xml on the Tomcat host. You need write permission to that file and permission to restart the Tomcat service. Back it up first so you can restore the previous configuration if the server fails to start.
<Realm className="org.apache.catalina.realm.JNDIRealm"
connectionURL="ldaps://ldap.example.com:636"
connectionName="cn=tomcat-bind,ou=services,dc=example,dc=com"
connectionPassword="replace-with-bind-password"
userBase="ou=people,dc=example,dc=com"
userSearch="(uid={0})"
roleBase="ou=groups,dc=example,dc=com"
roleName="cn"
roleSearch="(uniqueMember={0})"
connectionPool="true"
referral="follow"/>
connectionURL uses LDAPS over port 636 so the bind password and user credentials travel inside TLS. userSearch finds the entry logging in; {0} is replaced with the supplied username. roleSearch locates groups that list the authenticated user as a member, and roleName extracts the role name Tomcat uses for authorization.
Declare protected areas in web.xml
In each application's WEB-INF/web.xml, add a security constraint and login configuration. This example protects the entire application and requires the employee role.
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>employee</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/login-error.html</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>employee</role-name>
</security-role>
Tomcat maps the directory group names returned by roleSearch to these role-name values. If the directory returns cn=employee,ou=groups,..., the user is authorized.
Verify the authentication flow
- Restart Tomcat and watch
logs/catalina.outfor JNDI connection errors during startup. - Open a protected URL in a browser. You should be redirected to
/login.html. - Log in with a directory user who belongs to the mapped group. Access should succeed.
- Log in with a user outside that group. Tomcat should return 403 or show the error page.
If authentication fails, check catalina.out for messages such as invalid credentials, missing group membership, or TLS handshake failures. Increase logging for org.apache.catalina.realm if the default messages do not identify the LDAP filter mismatch.
Limitations and operational cautions
connectionPasswordappears in plaintext inserver.xml. Restrict file permissions to the Tomcat user and consider an external credential store if your policy forbids secrets in configuration files.- A broad
roleSearchcan grant more roles than intended. Test with a non-privileged user before rolling out to production. - LDAPS or StartTLS is required; plain LDAP exposes bind traffic on the network.
- Confirm your Tomcat patch level before using JNDIRealm in production; realm-related advisories have affected older releases.
Rollback
Because editing server.xml changes runtime state, keep the pre-edited copy. If Tomcat will not start or authentication breaks all applications, restore the backup, restart Tomcat, and re-test with a single non-production context.
Checklist before you finish
server.xmlparses without XML errors.- LDAPS port is reachable from the Tomcat host.
- Bind account can read
userBaseandroleBase. - One user in and one user out of the target role both behave as expected.
JNDIRealm removes directory logic from your applications, but it moves trust into Tomcat's configuration and network path. Test the in-group and out-of-group cases explicitly, and treat the bind password like any other production secret.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.