Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SpnegoAuthenticator allows wrong calls to login/logout methods #819

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

natalia-s-ivanova
Copy link

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":

/**
* Authenticate the provided user name and password and then associated the
* authenticated user with the request.
*
* ...
* 
* @throws ServletException If any of {@link #getRemoteUser()}, {@link
*           #getUserPrincipal()} or {@link #getAuthType()} are non-null, if the
*           configured authenticator does not support user name and password
*           authentication or if the authentication fails
*/

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:

<Realm className="org.apache.catalina.realm.JNDIRealm"       
    authentication="GSSAPI"
    ...
/>

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.

@markt-asf
Copy link
Contributor

Just a heads up that review of this will take a little longer as I need to get my SPNEGO test environment and and running again. I didn't see any issues in a quick code review but I want to explore a few things further in a test environment before making any code changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants