This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new 97cf06b083 Add ssoReauthenticationMode attribute to built-in
Authenticators
97cf06b083 is described below
commit 97cf06b083d4ec9a89ecb81b53c3f5347d00c4fd
Author: Mark Thomas <[email protected]>
AuthorDate: Fri Jan 9 16:39:56 2026 +0000
Add ssoReauthenticationMode attribute to built-in Authenticators
---
.../catalina/authenticator/AuthenticatorBase.java | 85 ++++++++++++----
.../authenticator/DigestAuthenticator.java | 2 -
.../catalina/authenticator/SSLAuthenticator.java | 2 -
.../catalina/authenticator/SingleSignOn.java | 9 ++
.../authenticator/SpnegoAuthenticator.java | 2 -
webapps/docs/changelog.xml | 5 +
webapps/docs/config/valve.xml | 110 +++++++++++++++++++++
7 files changed, 190 insertions(+), 25 deletions(-)
diff --git a/java/org/apache/catalina/authenticator/AuthenticatorBase.java
b/java/org/apache/catalina/authenticator/AuthenticatorBase.java
index 6961150583..6ea6f92008 100644
--- a/java/org/apache/catalina/authenticator/AuthenticatorBase.java
+++ b/java/org/apache/catalina/authenticator/AuthenticatorBase.java
@@ -218,6 +218,8 @@ public abstract class AuthenticatorBase extends ValveBase
implements Authenticat
*/
protected SingleSignOn sso = null;
+ private SsoReauthenticationMode ssoReauthenticationMode =
SsoReauthenticationMode.DEFAULT;
+
private AllowCorsPreflight allowCorsPreflight = AllowCorsPreflight.NEVER;
private volatile String jaspicAppContextID = null;
@@ -227,6 +229,15 @@ public abstract class AuthenticatorBase extends ValveBase
implements Authenticat
// ------------------------------------------------------------- Properties
+ public String getSsoReauthenticationMode() {
+ return ssoReauthenticationMode.name().toLowerCase(Locale.ENGLISH);
+ }
+
+ public void setSsoReauthenticationMode(String ssoReauthenticationMode) {
+ this.ssoReauthenticationMode =
+
SsoReauthenticationMode.valueOf(ssoReauthenticationMode.trim().toUpperCase(Locale.ENGLISH));
+ }
+
public String getAllowCorsPreflight() {
return allowCorsPreflight.name().toLowerCase(Locale.ENGLISH);
}
@@ -897,38 +908,66 @@ public abstract class AuthenticatorBase extends ValveBase
implements Authenticat
* Which cached authentication methods are used depends on the
configuration of the SSO Valve and/or the
* Authenticator.
*
- * If the SSO Valve is configured to require re-authentication, any
cached Principal will not be used.
+ * If the SSO Valve is configured to require re-authentication, any
cached Principal will not be used unless the
+ * Authenticator is explicitly configured (via
ssoReauthenticationMode) to use it.
*
* If the SSO Valve is configured to require re-authentication,
whether the cached user name and password can be
- * used will be determined by the calling Authenticator type.
+ * used will be determined by the calling Authenticator type unless
the Authenticator's ssoReauthenticationMode
+ * is explicitly configured.
*/
- // Has the user already been authenticated?
- Principal principal = request.getUserPrincipal();
+ // Determine which - if any - checks for cached authentication will be
made.
+ boolean checkPrincipal = false;
+ boolean checkPassword = false;
+
+ // Will be null if SSO is not configured or there is no current SSO
session
String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE);
- if (principal != null) {
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("authenticator.check.found",
principal.getName()));
- }
- // Associate the session with any existing SSO session. Even if
- // useSSO is false, this will ensure coordinated session
- // invalidation at log out.
+
+ if (sso == null) {
+ // There is no SSO - check in case some other component has set
the Principal
+ checkPrincipal = true;
+ } else if (ssoReauthenticationMode == SsoReauthenticationMode.DEFAULT
&& !sso.getRequireReauthentication() ||
+ ssoReauthenticationMode == SsoReauthenticationMode.PRINCIPAL) {
+ checkPrincipal = true;
+ // If checkPrincipal is enabled then checkPassword is enabled if
there is an SSO session
if (ssoId != null) {
- associate(ssoId, request.getSessionInternal(true));
+ checkPassword = true;
+ }
+ } else if (ssoId != null && (ssoReauthenticationMode ==
SsoReauthenticationMode.PASSWORD ||
+ sso.getRequireReauthentication() &&
useSsoCachedUserAndPassword)) {
+ checkPassword = true;
+ }
+
+ // Check for a cached Principal. Most likely from SSO but could be
another component.
+ if (checkPrincipal) {
+ if (ssoId != null && sso.getRequireReauthentication()) {
+ // There is a valid SSO session but SSO Valve won't have
cached the Principal.
+ sso.populateRequestFromSsoEntry(request, ssoId);
+ }
+
+ // Has the user already been authenticated?
+ Principal principal = request.getUserPrincipal();
+ if (principal != null) {
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("authenticator.check.found",
principal.getName()));
+ }
+ // Associate the session with any existing SSO session. Even if
+ // useSSO is false, this will ensure coordinated session
+ // invalidation at log out.
+ if (ssoId != null) {
+ associate(ssoId, request.getSessionInternal(true));
+ }
+ return true;
}
- return true;
}
- // Is there an SSO session against which we can try to reauthenticate?
- if (useSsoCachedUserAndPassword && ssoId != null) {
+ // Check for a user and password cached by SSO
+ if (checkPassword) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("authenticator.check.sso", ssoId));
}
/*
- * Try to reauthenticate using data cached by SSO. If this fails,
either the original SSO logon was of
- * DIGEST or SSL (which we can't reauthenticate ourselves because
there is no cached username and password),
- * or the realm denied the user's reauthentication for some
reason. In either case we have to prompt the
- * user for a logon
+ * Try to reauthenticate using data cached by SSO. If this fails
we have to prompt the user for credentials.
*/
if (reauthenticateFromSSO(ssoId, request)) {
return true;
@@ -1307,4 +1346,12 @@ public abstract class AuthenticatorBase extends
ValveBase implements Authenticat
FILTER,
ALWAYS
}
+
+
+ protected enum SsoReauthenticationMode {
+ DEFAULT,
+ PRINCIPAL,
+ PASSWORD,
+ FULL
+ }
}
diff --git a/java/org/apache/catalina/authenticator/DigestAuthenticator.java
b/java/org/apache/catalina/authenticator/DigestAuthenticator.java
index 2a8c8637ef..1625779b2b 100644
--- a/java/org/apache/catalina/authenticator/DigestAuthenticator.java
+++ b/java/org/apache/catalina/authenticator/DigestAuthenticator.java
@@ -272,8 +272,6 @@ public class DigestAuthenticator extends AuthenticatorBase {
* authentication. Reauthenticating with the cached user name and
password should be sufficient for DIGEST in
* that scenario. However, the original behaviour to reauthenticate
has been retained in case of any (very
* unlikely) backwards compatibility issues.
- *
- * TODO: Make the reauthentication behaviour configurable per
authenticator.
*/
if (checkForCachedAuthentication(request, response, false)) {
return true;
diff --git a/java/org/apache/catalina/authenticator/SSLAuthenticator.java
b/java/org/apache/catalina/authenticator/SSLAuthenticator.java
index 334892c78b..0c6834c5e6 100644
--- a/java/org/apache/catalina/authenticator/SSLAuthenticator.java
+++ b/java/org/apache/catalina/authenticator/SSLAuthenticator.java
@@ -69,8 +69,6 @@ public class SSLAuthenticator extends AuthenticatorBase {
* since it will not make any TLS information (client certificate etc)
available that a web application may
* depend on. Therefore, the reauthentication behaviour for
CLIENT-CERT is to perform a normal CLIENT-CERT
* authentication.
- *
- * TODO: Make the reauthentication behaviour configurable per
authenticator.
*/
if (checkForCachedAuthentication(request, response, false)) {
return true;
diff --git a/java/org/apache/catalina/authenticator/SingleSignOn.java
b/java/org/apache/catalina/authenticator/SingleSignOn.java
index 34215813b8..e117280331 100644
--- a/java/org/apache/catalina/authenticator/SingleSignOn.java
+++ b/java/org/apache/catalina/authenticator/SingleSignOn.java
@@ -503,6 +503,15 @@ public class SingleSignOn extends ValveBase {
}
+ protected void populateRequestFromSsoEntry(Request request, String ssoId) {
+ SingleSignOnEntry entry = cache.get(ssoId);
+ if (entry != null) {
+ request.setAuthType(entry.getAuthType());
+ request.setUserPrincipal(entry.getPrincipal());
+ }
+ }
+
+
/**
* Register the specified Principal as being associated with the specified
value for the single sign on identifier.
*
diff --git a/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
b/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
index 05744af657..69f9e01147 100644
--- a/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
+++ b/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
@@ -143,8 +143,6 @@ public class SpnegoAuthenticator extends AuthenticatorBase {
* Reauthenticating with the cached user name and password may not be
sufficient for SPNEGO since it will not
* make the delegated credentials available that a web application may
depend on. Therefore, the
* reauthentication behaviour for SPNEGO is to perform a normal SPNEGO
authentication.
- *
- * TODO: Make the reauthentication behaviour configurable per
authenticator.
*/
if (checkForCachedAuthentication(request, response, false)) {
return true;
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 5938309a74..fb6609d55c 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -125,6 +125,11 @@
Update the minimum and recommended versions for Tomcat Native to 1.3.4.
(markt)
</update>
+ <add>
+ Add a new <code>ssoReauthenticationMode</code> to the Tomcat provided
+ Authenticators that provides a per Authenticator override of the SSO
+ Valve <code>requireReauthentication</code> attribute. (markt)
+ </add>
</changelog>
</subsection>
<subsection name="Coyote">
diff --git a/webapps/docs/config/valve.xml b/webapps/docs/config/valve.xml
index f98cf53023..8993423614 100644
--- a/webapps/docs/config/valve.xml
+++ b/webapps/docs/config/valve.xml
@@ -1576,6 +1576,28 @@
If not specified, the default value is <code>false</code>.</p>
</attribute>
+ <attribute name="ssoReauthenticationMode" required="false">
+ <p>Provides a per Authenicator override of the SSO Valve attribute
+ <code>requireReauthentication</code>. It has the following options:</p>
+ <dl>
+ <dt>default</dt>
+ <dd>Reauthentication behaviour depends on the SSO Valve configuration
+ and the authentictaor type.</dd>
+ <dt>principal</dt>
+ <dd>The authenticator will look first for a cached Principal. If none
+ is found, the authenticator will look for a cached user name and
+ password and attempt to use them to reauthenticate. If that
fails,
+ a normal authentication will be performed.</dd>
+ <dt>password</dt>
+ <dd>The authenticator will look for a cached user name and password
+ and attempt to use them to reauthenticate. If that fails, a
normal
+ authentication will be performed.</dd>
+ <dt>full</dt>
+ <dd>Only a normal authentication will be performed. The SSO Valve is
+ effectively ignored.</dd>
+ </dl>
+ </attribute>
+
<attribute name="trimCredentials" required="false">
<p>Controls whether leading and/or trailing whitespace is removed from
the parsed credentials. If not specified, the default value is
@@ -1766,6 +1788,28 @@
If not specified, the default value is <code>false</code>.</p>
</attribute>
+ <attribute name="ssoReauthenticationMode" required="false">
+ <p>Provides a per Authenicator override of the SSO Valve attribute
+ <code>requireReauthentication</code>. It has the following options:</p>
+ <dl>
+ <dt>default</dt>
+ <dd>Reauthentication behaviour depends on the SSO Valve configuration
+ and the authentictaor type.</dd>
+ <dt>principal</dt>
+ <dd>The authenticator will look first for a cached Principal. If none
+ is found, the authenticator will look for a cached user name and
+ password and attempt to use them to reauthenticate. If that
fails,
+ a normal authentication will be performed.</dd>
+ <dt>password</dt>
+ <dd>The authenticator will look for a cached user name and password
+ and attempt to use them to reauthenticate. If that fails, a
normal
+ authentication will be performed.</dd>
+ <dt>full</dt>
+ <dd>Only a normal authentication will be performed. The SSO Valve is
+ effectively ignored.</dd>
+ </dl>
+ </attribute>
+
<attribute name="validateUri" required="false">
<p>Should the URI be validated as required by RFC2617? If not
specified,
the default value of <code>true</code> will be used. This should
@@ -1923,6 +1967,28 @@
If not specified, the default value is <code>false</code>.</p>
</attribute>
+ <attribute name="ssoReauthenticationMode" required="false">
+ <p>Provides a per Authenicator override of the SSO Valve attribute
+ <code>requireReauthentication</code>. It has the following options:</p>
+ <dl>
+ <dt>default</dt>
+ <dd>Reauthentication behaviour depends on the SSO Valve configuration
+ and the authentictaor type.</dd>
+ <dt>principal</dt>
+ <dd>The authenticator will look first for a cached Principal. If none
+ is found, the authenticator will look for a cached user name and
+ password and attempt to use them to reauthenticate. If that
fails,
+ a normal authentication will be performed.</dd>
+ <dt>password</dt>
+ <dd>The authenticator will look for a cached user name and password
+ and attempt to use them to reauthenticate. If that fails, a
normal
+ authentication will be performed.</dd>
+ <dt>full</dt>
+ <dd>Only a normal authentication will be performed. The SSO Valve is
+ effectively ignored.</dd>
+ </dl>
+ </attribute>
+
</attributes>
</subsection>
@@ -2039,6 +2105,28 @@
specified, the platform default provider will be used.</p>
</attribute>
+ <attribute name="ssoReauthenticationMode" required="false">
+ <p>Provides a per Authenicator override of the SSO Valve attribute
+ <code>requireReauthentication</code>. It has the following options:</p>
+ <dl>
+ <dt>default</dt>
+ <dd>Reauthentication behaviour depends on the SSO Valve configuration
+ and the authentictaor type.</dd>
+ <dt>principal</dt>
+ <dd>The authenticator will look first for a cached Principal. If none
+ is found, the authenticator will look for a cached user name and
+ password and attempt to use them to reauthenticate. If that
fails,
+ a normal authentication will be performed.</dd>
+ <dt>password</dt>
+ <dd>The authenticator will look for a cached user name and password
+ and attempt to use them to reauthenticate. If that fails, a
normal
+ authentication will be performed.</dd>
+ <dt>full</dt>
+ <dd>Only a normal authentication will be performed. The SSO Valve is
+ effectively ignored.</dd>
+ </dl>
+ </attribute>
+
</attributes>
</subsection>
@@ -2217,6 +2305,28 @@
If not specified, the default value is <code>false</code>.</p>
</attribute>
+ <attribute name="ssoReauthenticationMode" required="false">
+ <p>Provides a per Authenicator override of the SSO Valve attribute
+ <code>requireReauthentication</code>. It has the following options:</p>
+ <dl>
+ <dt>default</dt>
+ <dd>Reauthentication behaviour depends on the SSO Valve configuration
+ and the authentictaor type.</dd>
+ <dt>principal</dt>
+ <dd>The authenticator will look first for a cached Principal. If none
+ is found, the authenticator will look for a cached user name and
+ password and attempt to use them to reauthenticate. If that
fails,
+ a normal authentication will be performed.</dd>
+ <dt>password</dt>
+ <dd>The authenticator will look for a cached user name and password
+ and attempt to use them to reauthenticate. If that fails, a
normal
+ authentication will be performed.</dd>
+ <dt>full</dt>
+ <dd>Only a normal authentication will be performed. The SSO Valve is
+ effectively ignored.</dd>
+ </dl>
+ </attribute>
+
<attribute name="storeDelegatedCredential" required="false">
<p>Controls if the user' delegated credential will be stored in
the user Principal. If available, the delegated credential will be
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]