SpnegoAuthenticator allows wrong calls to login/logout methods #819
+132
−1
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary:
Inconsistent behavior of the HttpServletRequest.login(..) method when using SpnegoAuthenticator for WEB application in Tomcat 11.0.2 and earlier.
Details:
Although SpnegoAuthenticator does not implement any public spec interface, usage of this Authenticator leads to violation of contract of HttpServletRequest.login(..) method.
Documentation of the HttpServletRequest.login(..) says that it should either "authenticate the provided user name and password" or throw ServletException "if the configured authenticator does not support user name and password authentication":
Neither of these actions are performed when using SpnegoAuthenticator: (1) ServletException is not thrown, (2) password is not verified against an existing user name (ANY password could be passed into this method and authentication is considered to be successful).
Example:
We have the Tomcat server 11.0.2 that is configured to use SpnegoAuthenticator as a valve in combination with JNDIRealm (LDAP configuration) for a specific application. JNDIRealm is configured in the following way:
We performed all the Tomcat setup to use Kerberos tickets for user authentication.
While working the application is able to call HttpServletRequest.logout() and afterwards HttpServletRequest.login(..) methods. We identified that in this configuration (authentication="GSSAPI") calling the HttpServletRequest.login(..) method with ANY existing LDAP user does NOT perform password check and allows getting ANOTHER principal to be used by application with its LDAP roles.
Solution:
It looks like the most correct way to fix this issue is to make SpnegoAuthenticator throw ServletException on its login method. Also it looks like such "loginless" implementations should not allow 'logout' operation, but org.apache.catalina.Authenticator.logout(..) does not have ServletException in its signature, so we introduced 'UnsupportedOperationException' in logout for the loginless type of authenticators.