On Wed, Nov 26, 2025 at 8:54 PM Mark Thomas <[email protected]> wrote:
>
> I've been looking into PR #890 [1] - "Make SSO re-authentication
> configurable for SSLAuthenticator". The short version is that I think
> some of the current code comments aren't quite right and that there
> might be scope to simply SSO. Additional documentation is almost
> certainly required.
>
> There are quite a few moving parts to this. Apologies for the length of
> what follows.
>
> I'm ignoring session expiry, authentication failure etc to keep things
> simple so we can focus on the bits that I think are important to this
> discussion.
>
> When I refer to full authentication I mean that the authenticator has
> taken the normal credentials the authenticator requires (provided by the
> user or cached by SSO) and used them to call the appropriate
> Realm.authenticate() method and received a newly created, authenticated
> Principal in response. Any case where a cached Principal is re-used
> (e.g. based on the presence of an SSO cookie) is not full authentication.

Yes, I had a look at the code since it has been a while, and there are
two levels: the main requireReauthentication in SingleSignOn and then
the checkForCachedAuthentication(..., useSSO).

> First the (fairly) simple case.
>
> SSO requires that all web applications under the Host/Engine where SSO
> is configured use the same Realm.
> The SSO Valve processes the request before the Authenticators do.
> The authenticators look for an SSO Valve when they start up and, if
> found, retain a reference to it.
> Any full authentication by any authenticator is registered with the SSO
> Valve which caches the authenticated Principal (and a few other bits and
> pieces) and an SSO cookie is sent to the client.
> The SSO Valve looks for the cookie and, if it is set, looks up the
> associated authenticated Principal and adds it to the request.
> The authenticators check to see if the request already has a Principal
> and, if it does, use it rather than performing a full authentication of
> the user.
>
> Then we get bug 23881 [2]. Unfortunately, "fail to authenticate
> correctly" is not defined. Reading between the lines, the underlying
> issue is that the application is depending on more than just the
> Principal being added to the request. Bug 23881 mentions JAAS but I'm
> not sure what role that was playing - unless it was a custom JAAS realm.
> It might have been since JBoss was mentioned. The solution was to
> introduce the concept of re-authentication. With re-authentication, the
> authenticators always complete a full authentication even with SSO. This
> means one of the Realm.authenticate() methods will be called which
> strongly suggests the Realm is doing something additional that the
> application depends on in addition to the setting of the Principal on
> the request.
>
> To avoid repeatedly prompting users with FORM auth (if one of the web
> applications uses it) the SSO Valve caches the plain text user name and
> password captured from BASIC or FORM auth and then re-uses them if it
> needs to re-authenticate for a web application using BASIC or FORM.
> Strictly that isn't necessary for BASIC since the client will re-send
> the credentials on every request.
>
> DIGEST and CLIENT-CERT authenticators can't perform a full
> authentication with a plain text username and password so the
> Authenticator completes a full authentication by obtaining the
> information from the request. The client typically sends the credentials
> for DIGEST on every request so the user isn't repeatedly prompted for
> credentials.
>
> There is an interesting edge case here that if digested passwords are
> being used with DIGEST authentication the password stored in the Realm
> will need to be different for DIGEST compared to BASIC/FORM so it would
> not be possible to mix DIGEST with FORM or BASIC in an SSO configuration
> with digested passwords. This needs documenting.
>
> Depending on what the Realm is doing / application is expecting, it may
> be sufficient for a DIGEST authenticator to re-authenticate to the Realm
> using the cached plain-text user name and password from BASIC/FORM auth.
>
> SPNEGO will re-authenticate with a user name and password from
> BASIC/FORM. That looks odd to me since if re-authentication has been
> enabled, I would expect SPNEGO to complete a full SPNEGO authentication.
> I think this is a bug that needs to be fixed.

Yes. I guess it sounds a bit magical and cut and pasting is tempting.
I think this is where it comes from.

> PR #890 is - essentially - a request to make re-authentication
> configurable for the SSLAuthenticator when the SSO Valve is configured
> to require it.
>
> The code comments suggest that re-authentication is to do with the
> relative security of the authentication mechanisms. I think this is
> incorrect. I think it is whether an authenticator can complete a full
> (against the Realm) authentication with the cached, plain-text user name
> and password. Whether it can is going to depend on exactly what the
> Realm is doing that application is depending on. I intend to update the
> comments to that effect.

I agree that Tomcat gets the principal "securely" and caching it does
not make it less secure.

> If re-authentication is enabled for the SSO Valve it makes the SSO Valve
> essentially pointless unless there is more than one Context that can
> re-authenticate from the cached username and password. That is worth
> documenting for the requireReauthentication attribute of the SSL Valve.
>
> Getting back to #890, I wondered if the solution for the OP would be to
> disable re-authentication on the SSO Valve. That would have the same
> effect. That got me thinking there maybe cases where re-authentication
> is required for some, but not all, web applications under an SSO Valve.
>
> There are, currently, 3 authentication possibilities for a web
> application using SSO.
> 1. Cached user Principal from SSO session is added to request
>     (Default)
>
> 2. User is re-authenticated against Realm using cached plain
>     text user name and password from SSO session
>     (BASIC, FORM and SPNEGO when requireReauthentication is set)
>
> 3. User is fully re-authenticated using against the Realm using
>     credentials from the request (as if SSO was not present)
>     (DIGEST and CLIENT-CERT when requireReauthentication is set)

+1 good summary.

>
> So, finally, to potential changes.
>
> I had considered removing the requireReauthentication attribute from the
> SSO Valve but I think it still serves a purpose and is worth keeping.
> Removing it would also create migration work for users. I proposed the
> following:
> - add an ssoReauthenticationMode to the Authenticator interface with
>    three possible values (all case insensitive)
>    - cached - add the cached Principal to the request
>    - userPassword - authenticate to the Realm with the cached
>                     username and password from BASIC/FORM
>    - full - perform the standard authentication for the authenticator
>             using information provided in the request

I don't understand how the "cached" value works since it conflicts
with the value of the requireReauthentication flag from SingleSignOn.
Then this sounds like ending up changing the
checkForCachedAuthentication method signature since the useSSO flag is
not useful.  Any custom authenticator would use it (I mean: have cut
and pasted the code that calls it to do the magical stuff, from the
BasicAuthenticator code :) ), so maybe a bad plan.

> - if requireReauthentication is not enabled, all authenticators
>    use the "cached" mode (no change)
> - if requireReauthentication is enabled
>     - BASIC and FORM reauthenticate use "userPassword" mode by default
>       (no change).
>     - SPNEGO used "full" mode by default (change)

+1 for changing this one.

>     - DIGEST and CLIENT-CERT used "full" mode by default (no change)
>     - individual authenticators can override the default
>       re-authentication mode to one of cached, userPassword, full
>
> There is an argument to switch DIGEST to "userPassword" mode by default
> if requireReauthentication is enabled but I'm not sure there is enough
> of a reason to change the current behaviour.
>
> If you followed my ramblings this far - thank you. Thoughts?

I missed something.

Rémy

> Mark
>
>
> [1] https://github.com/apache/tomcat/pull/890
> [2] https://bz.apache.org/bugzilla/show_bug.cgi?id=23881
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to