diff --git a/lib/trino-hdfs/src/main/java/io/trino/hdfs/authentication/KerberosHadoopAuthentication.java b/lib/trino-hdfs/src/main/java/io/trino/hdfs/authentication/KerberosHadoopAuthentication.java index 7898b8b2b6ef..f7d41bac7c2a 100644 --- a/lib/trino-hdfs/src/main/java/io/trino/hdfs/authentication/KerberosHadoopAuthentication.java +++ b/lib/trino-hdfs/src/main/java/io/trino/hdfs/authentication/KerberosHadoopAuthentication.java @@ -56,7 +56,7 @@ private KerberosHadoopAuthentication(KerberosAuthentication kerberosAuthenticati @Override public UserGroupInformation getUserGroupInformation() { - Subject subject = kerberosAuthentication.getSubject(); + Subject subject = kerberosAuthentication.getLoginContext().getSubject(); return createUserGroupInformationForSubject(subject); } } diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/authentication/CachingKerberosAuthentication.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/authentication/CachingKerberosAuthentication.java index c448a566d4ca..2f2547f95b70 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/authentication/CachingKerberosAuthentication.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/authentication/CachingKerberosAuthentication.java @@ -16,6 +16,8 @@ import javax.annotation.concurrent.GuardedBy; import javax.security.auth.Subject; import javax.security.auth.kerberos.KerberosTicket; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; import static io.trino.plugin.base.authentication.KerberosTicketUtils.getTicketGrantingTicket; import static java.util.Objects.requireNonNull; @@ -25,7 +27,7 @@ public class CachingKerberosAuthentication private final KerberosAuthentication kerberosAuthentication; @GuardedBy("this") - private Subject subject; + private LoginContext loginContext; @GuardedBy("this") private long nextRefreshTime; @@ -37,19 +39,28 @@ public CachingKerberosAuthentication(KerberosAuthentication kerberosAuthenticati public synchronized Subject getSubject() { - if (subject == null || ticketNeedsRefresh()) { - subject = requireNonNull(kerberosAuthentication.getSubject(), "kerberosAuthentication.getSubject() is null"); + if (loginContext == null || ticketNeedsRefresh()) { + loginContext = kerberosAuthentication.getLoginContext(); + Subject subject = getRequiredSubject(); KerberosTicket tgtTicket = getTicketGrantingTicket(subject); nextRefreshTime = KerberosTicketUtils.getRefreshTime(tgtTicket); + return subject; } - return subject; + return getRequiredSubject(); } public synchronized void reauthenticateIfSoonWillBeExpired() { - requireNonNull(subject, "subject is null, getSubject() must be called before reauthenticate()"); + requireNonNull(loginContext, "loginContext is null. getSubject must be called before reauthenticateIfSoonWillBeExpired"); if (ticketNeedsRefresh()) { - kerberosAuthentication.attemptLogin(subject); + Subject subject = getRequiredSubject(); + try { + loginContext.logout(); + loginContext = kerberosAuthentication.loginFromSubject(subject); + } + catch (LoginException e) { + throw new RuntimeException(e); + } KerberosTicket tgtTicket = getTicketGrantingTicket(subject); nextRefreshTime = KerberosTicketUtils.getRefreshTime(tgtTicket); } @@ -59,4 +70,9 @@ private boolean ticketNeedsRefresh() { return nextRefreshTime < System.currentTimeMillis(); } + + private Subject getRequiredSubject() + { + return requireNonNull(loginContext.getSubject(), "loginContext.getSubject() is null"); + } } diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/authentication/KerberosAuthentication.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/authentication/KerberosAuthentication.java index 99b227132584..93d4c46ffd64 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/authentication/KerberosAuthentication.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/authentication/KerberosAuthentication.java @@ -42,27 +42,18 @@ public KerberosAuthentication(KerberosConfiguration kerberosConfiguration) this.configuration = kerberosConfiguration.getConfiguration(); } - public Subject getSubject() + public LoginContext getLoginContext() { Subject subject = new Subject(false, ImmutableSet.of(principal), emptySet(), emptySet()); - try { - LoginContext loginContext = new LoginContext("", subject, null, configuration); - loginContext.login(); - return loginContext.getSubject(); - } - catch (LoginException e) { - throw new RuntimeException(e); - } + return loginFromSubject(subject); } - public void attemptLogin(Subject subject) + public LoginContext loginFromSubject(Subject subject) { try { - synchronized (subject.getPrivateCredentials()) { - subject.getPrivateCredentials().clear(); - LoginContext loginContext = new LoginContext("", subject, null, configuration); - loginContext.login(); - } + LoginContext loginContext = new LoginContext("", subject, null, configuration); + loginContext.login(); + return loginContext; } catch (LoginException e) { throw new RuntimeException(e);