This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 59aa7f2e8e30aa73bafcefc56000506efb2c0a70 Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Jul 24 17:53:22 2024 +0100 Refactor SpnegoAuthenticator to use Subject.callAs() when available --- .../authenticator/SpnegoAuthenticator.java | 67 +++++----------------- webapps/docs/changelog.xml | 5 ++ 2 files changed, 19 insertions(+), 53 deletions(-) diff --git a/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java b/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java index 8bed63a40e..570ce65413 100644 --- a/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java +++ b/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java @@ -19,11 +19,9 @@ package org.apache.catalina.authenticator; import java.io.File; import java.io.IOException; import java.security.Principal; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Base64; import java.util.LinkedHashMap; +import java.util.concurrent.CompletionException; import java.util.regex.Pattern; import javax.security.auth.Subject; @@ -33,12 +31,12 @@ import javax.security.auth.login.LoginException; import jakarta.servlet.http.HttpServletResponse; import org.apache.catalina.LifecycleException; -import org.apache.catalina.Realm; import org.apache.catalina.connector.Request; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.buf.MessageBytes; +import org.apache.tomcat.util.compat.JreCompat; import org.apache.tomcat.util.compat.JreVendor; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSCredential; @@ -134,7 +132,6 @@ public class SpnegoAuthenticator extends AuthenticatorBase { } - @SuppressWarnings("removal") @Override protected boolean doAuthenticate(Request request, HttpServletResponse response) throws IOException { @@ -211,11 +208,15 @@ public class SpnegoAuthenticator extends AuthenticatorBase { } else { credentialLifetime = GSSCredential.DEFAULT_LIFETIME; } - final PrivilegedExceptionAction<GSSCredential> action = () -> manager.createCredential(null, - credentialLifetime, new Oid("1.3.6.1.5.5.2"), GSSCredential.ACCEPT_ONLY); - gssContext = manager.createContext(Subject.doAs(subject, action)); + gssContext = manager.createContext(JreCompat.getInstance().callAs(subject, () -> { + return manager.createCredential(null, credentialLifetime, new Oid("1.3.6.1.5.5.2"), + GSSCredential.ACCEPT_ONLY); + })); - outToken = Subject.doAs(lc.getSubject(), new AcceptAction(gssContext, decoded)); + final GSSContext gssContextFinal = gssContext; + outToken = JreCompat.getInstance().callAs(subject, () -> { + return gssContextFinal.acceptSecContext(decoded, 0, decoded.length); + }); if (outToken == null) { if (log.isDebugEnabled()) { @@ -227,9 +228,9 @@ public class SpnegoAuthenticator extends AuthenticatorBase { return false; } - principal = Subject.doAs(subject, - new AuthenticateAction(context.getRealm(), gssContext, storeDelegatedCredential)); - + principal = JreCompat.getInstance().callAs(subject, () -> { + return context.getRealm().authenticate(gssContextFinal, storeDelegatedCredential); + }); } catch (GSSException e) { if (log.isDebugEnabled()) { log.debug(sm.getString("spnegoAuthenticator.ticketValidateFail"), e); @@ -237,7 +238,7 @@ public class SpnegoAuthenticator extends AuthenticatorBase { response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE); response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return false; - } catch (PrivilegedActionException e) { + } catch (CompletionException e) { Throwable cause = e.getCause(); if (cause instanceof GSSException) { if (log.isDebugEnabled()) { @@ -295,46 +296,6 @@ public class SpnegoAuthenticator extends AuthenticatorBase { } - /** - * This class gets a gss credential via a privileged action. - */ - public static class AcceptAction implements PrivilegedExceptionAction<byte[]> { - - GSSContext gssContext; - - byte[] decoded; - - public AcceptAction(GSSContext context, byte[] decodedToken) { - this.gssContext = context; - this.decoded = decodedToken; - } - - @Override - public byte[] run() throws GSSException { - return gssContext.acceptSecContext(decoded, 0, decoded.length); - } - } - - - public static class AuthenticateAction implements PrivilegedAction<Principal> { - - private final Realm realm; - private final GSSContext gssContext; - private final boolean storeDelegatedCredential; - - public AuthenticateAction(Realm realm, GSSContext gssContext, boolean storeDelegatedCredential) { - this.realm = realm; - this.gssContext = gssContext; - this.storeDelegatedCredential = storeDelegatedCredential; - } - - @Override - public Principal run() { - return realm.authenticate(gssContext, storeDelegatedCredential); - } - } - - /** * This class implements a hack around an incompatibility between the SPNEGO implementation in Windows and the * SPNEGO implementation in Java 8 update 40 onwards. It was introduced by the change to fix this bug: diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index c798172801..3472ce84a6 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -121,6 +121,11 @@ processes this as a simple CORS request. Based on a patch suggested by thebluemountain. (markt) </fix> + <fix> + Refactor <code>SpnegoAuthenticator</code> so it uses + <code>Subject.callAs()</code> rather than <code>Subject.doAs()</code> + when the available. (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org