Am 2021-09-14 um 18:23 schrieb Tim Miller Dyck:
Hello,
I wanted to report an issue with Tomcat LDAP user authentication lookups with
Tomcat container Kerberos security that I found in our environment when
upgrading to version Tomcat 9.0.52 from 9.0.30 and what configuration settings
bypassed the problem.
Here is our base pre-Tomcat upgrade configuration which was working for both
LDAP user authentication and with Kerberos-enabled authentication (e.g. with
the Tomcat Manager app).
* Tomcat 9.0.30 running on Windows Server 2019
* Microsoft OpenJDK packaging, build 11.0.12+7 64-bit
* Tomcat is authenticating users using LDAP queries to Windows Server
2012R2 Active Directory controllers
* Tomcat server.xml LDAP configuration:
<Realm className="org.apache.catalina.realm.JNDIRealm"
connectionURL="ldaps://dc1.myorg.com:636"
alternateURL="ldaps://dc2.myorg.com:636"
connectionName="dedicated-tomcat-ldap-u...@myorg.com"
connectionPassword="user-secret-password"
userBase="dc=myorg,dc=com"
userSearch="(&(objectClass=user)(sAMAccountName={0}))"
userSubtree="true"
roleBase="dc=myorg,dc=com"
roleSearch="(&(objectClass=group)(member={0}))"
roleSubtree="true"
roleNested="true"
roleName="cn"
adCompat="true"
/>
* We have some web apps that use Tomcat container Kerberos authentication,
e.g. we configure the Tomcat Manager app WEB-INF\web.xml with
<!-- Define the Login Configuration for this Application -->
<login-config>
<!-- Customization: switch Manager app authentication to use SPNEGO
(Kerberos) to get transparent authentication instead of using BASIC auth with a login
popup -->
<auth-method>SPNEGO</auth-method>
<realm-name>Tomcat Manager Application</realm-name>
</login-config>
The same configuration was then upgraded to Tomcat 9.0.52 with otherwise all
the same overall configuration in place (Kerberos settings, Java settings, cert
settings, etc.).
The following problem then appeared when trying to log into the Manager app
using SPNEGO/Kerberos (and also our web apps using Tomcat container Kerberos
authentication).
From the Tomcat stderr file:
14-Sep-2021 07:00:32.196 SEVERE [https-jsse-nio-443-exec-10]
org.apache.catalina.realm.JNDIRealm.getPrincipal Exception performing
authentication
javax.naming.NamingException: LDAP connection has been closed; remaining name
'dc=myorg,dc=com'
at java.naming/com.sun.jndi.ldap.LdapRequest.getReplyBer(LdapRequest.java:133)
at java.naming/com.sun.jndi.ldap.Connection.readReply(Connection.java:443)
at java.naming/com.sun.jndi.ldap.LdapClient.getSearchReply(LdapClient.java:639)
at java.naming/com.sun.jndi.ldap.LdapClient.search(LdapClient.java:562)
at java.naming/com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:2014)
at java.naming/com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1873)
at java.naming/com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1798)
at
java.naming/com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:392)
at
java.naming/com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:358)
at
java.naming/com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:341)
at
java.naming/javax.naming.directory.InitialDirContext.search(InitialDirContext.java:267)
at org.apache.catalina.realm.JNDIRealm.getUserBySearch(JNDIRealm.java:1610)
at org.apache.catalina.realm.JNDIRealm.getUser(JNDIRealm.java:1447)
at org.apache.catalina.realm.JNDIRealm.getUser(JNDIRealm.java:1376)
at org.apache.catalina.realm.JNDIRealm.getPrincipal(JNDIRealm.java:2352)
at org.apache.catalina.realm.JNDIRealm.getPrincipal(JNDIRealm.java:2288)
at org.apache.catalina.realm.JNDIRealm.getPrincipal(JNDIRealm.java:2269)
at org.apache.catalina.realm.RealmBase.authenticate(RealmBase.java:504)
at org.apache.catalina.realm.CombinedRealm.authenticate(CombinedRealm.java:365)
at org.apache.catalina.realm.LockOutRealm.authenticate(LockOutRealm.java:194)
...
In testing with Tomcat ver. 9.0.52, I found the following:
* Using Manager with basic auth but still with LDAP user lookups worked -
only Kerberos-enabled apps had problems with LDAP auth
* Switching our connectionURLs to use non-encrypted LDAP instead of LDAPS
caused the problem to be resolved and LDAP+Kerberos to work again so it was
something to do with use of SSL with LDAP (but we only want to use LDAPS, of
course, for security)
* In the LDAP server.xml configuration, as per Tomcat documentation, these
two settings are the defaults if not otherwise specified:
useDelegatedCredential="true"
spnegoDelegationQop="auth-conf "
* As per documentation, these settings cause a users's Kerberos
credentials to be used for the LDAP lookup (if Kerberos credentials are
available to Tomcat) instead of the specific LDAP connection username and
password in the JNDIRealm configuration.
* I tried setting stripRealmForGss="false" (the default is true, where the
domain is stripped from the username) - but has the same problem with both true and false
settings
* I tried adding only the line spnegoDelegationQop="auth" and this caused
the problem to be resolved with Kerberos+LDAP working again
* The options for spnegoDelegationQop are auth-conf (default, "authentication plus integrity and
confidentiality protection"), auth-int ("authentication plus integrity") and auth
("authentication only").
* I also tried auth-int, but this had the same
"org.apache.catalina.realm.JNDIRealm.getPrincipal Exception performing
authentication" error
* I then tested by adding only the line useDelegatedCredential="false" and
this also caused the problem to be resolved with Kerberos+LDAP working again (presumably
by having our Tomcat LDAP user used always for LDAP connection authentication and not
using the end user's Kerberos credential for the LDAP connection)
As additional information, if relevant, our Windows domain controllers have the
following LDAP connection security setting:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\LdapEnforceChannelBinding
= 1
From the Microsoft KB article at
https://support.microsoft.com/en-us/topic/use-the-ldapenforcechannelbinding-registry-entry-to-make-ldap-authentication-over-ssl-tls-more-secure-e9ecfa27-5e57-8519-6ba3-d2c06b21812e
DWORD value: 1 indicates enabled, when supported. All clients that are running
on a version of Windows that has been updated to support channel binding tokens
(CBT) must provide channel binding information to the server. Clients that are
running a version of Windows that has not been updated to support CBT do not
have to do so. This is an intermediate option that allows for application
compatibility.
I also tested previous versions of Tomcat and found the LDAP+Kerberos problem
described started with Tomcat v9.0.31 (and worked with Tomcat v9.0.30).
My conclusion so far is that when using LDAP+Kerberos with Tomcat 9.0.52, the
spnegoDelegationQop values of auth-conf and auth-int don't successfully
authenticate any longer against our Windows domain controllers, but Tomcat
9.0.30 (using the default auth-conf setting as I had not specified this setting
at all) did authenticate successfully. Given that the problem starts with the
auth-int setting, maybe the issue is the Kerberos delegation integrity
connection setting.
Going through the Tomcat changelogs, the bug report could be related as it
describes changes in this code area first released in Tomcat v9.0.31:
https://bz.apache.org/bugzilla/show_bug.cgi?id=64011
This may well be some subtle interaction between Tomcat, the JVM and our Active
Directory servers and may not be a Tomcat problem at all. I wanted to report it
for comment and to let others know who may find the same issue in their own
environments what worked for me so far.
It is very hard to answer to your requst because you mix a lot of things
which do not belong together.
E.g.,
> javax.naming.NamingException: LDAP connection has been closed;
remaining name 'dc=myorg,dc=com'
>
> at
java.naming/com.sun.jndi.ldap.LdapRequest.getReplyBer(LdapRequest.java:133)
The other side or a middle box dropped the TCP connection. Likely RST
sent. Nothing special. You are subject to bug:
https://bugs.openjdk.java.net/browse/JDK-8273402 I have reported
recently. Tomcat cannot properly recover from. If you have channels, try
to have this fix backported to 8, 11 and 17.
See my post "JNDIRealm does not retry on read timeouts or closed
connections" from two weeks ago.
What is your actual request here? How to make LDAPS work? How to achieve
LDAP Channel Binding? How to use Kerberos authentication without
credential delegation?
M
PS: The JNDIRealm is way too generic to properly be usable with Active
Directory
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org