This is an automated email from the ASF dual-hosted git repository.
pzampino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new 8d28295 KNOX-1850 - KnoxSession should honor the current subject for
Kerberos login
8d28295 is described below
commit 8d28295454013cfe50eb98ca97f18fa51beb80e7
Author: pzampino <[email protected]>
AuthorDate: Mon Apr 8 22:05:04 2019 -0400
KNOX-1850 - KnoxSession should honor the current subject for Kerberos login
---
.../org/apache/knox/gateway/shell/KnoxSession.java | 91 ++++++++++++----------
.../knox/gateway/shell/KnoxShellMessages.java | 3 +
.../apache/knox/gateway/shell/KnoxSessionTest.java | 61 ++++++++++++++-
3 files changed, 109 insertions(+), 46 deletions(-)
diff --git
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxSession.java
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxSession.java
index 3179642..a6c0fb6 100644
--- a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxSession.java
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxSession.java
@@ -102,6 +102,23 @@ public class KnoxSession implements Closeable {
public static final String BEGIN_CERTIFICATE = "-----BEGIN
CERTIFICATE-----\n";
private static final KnoxShellMessages LOG =
MessagesFactory.get(KnoxShellMessages.class);
+
+ private static final CredentialsProvider EMPTY_CREDENTIALS_PROVIDER = new
BasicCredentialsProvider();
+ static {
+ EMPTY_CREDENTIALS_PROVIDER.setCredentials(AuthScope.ANY,
+ new Credentials() {
+ @Override
+ public Principal
getUserPrincipal () {
+ return null;
+ }
+
+ @Override
+ public String getPassword ()
{
+ return null;
+ }
+ });
+ }
+
private boolean isKerberos;
private URL jaasConfigURL;
@@ -312,46 +329,32 @@ public class KnoxSession implements Closeable {
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
- final CredentialsProvider credentialsProvider = new
BasicCredentialsProvider();
-
- credentialsProvider.setCredentials(AuthScope.ANY, new Credentials() {
- @Override
- public Principal getUserPrincipal() {
- return null;
- }
-
- @Override
- public String getPassword() {
- return null;
- }
- });
-
- final Registry<AuthSchemeProvider> authSchemeRegistry =
RegistryBuilder.<AuthSchemeProvider>create()
- .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true)).build();
+ final Registry<AuthSchemeProvider> authSchemeRegistry =
+
RegistryBuilder.<AuthSchemeProvider>create().register(AuthSchemes.SPNEGO, new
SPNegoSchemeFactory(true)).build();
- return HttpClients.custom().setConnectionManager(connectionManager)
- .setDefaultAuthSchemeRegistry(authSchemeRegistry)
- .setDefaultCredentialsProvider(credentialsProvider).build();
+ return HttpClients.custom()
+ .setConnectionManager(connectionManager)
+ .setDefaultAuthSchemeRegistry(authSchemeRegistry)
+
.setDefaultCredentialsProvider(EMPTY_CREDENTIALS_PROVIDER)
+ .build();
} else {
AuthCache authCache = new BasicAuthCache();
BasicScheme authScheme = new BasicScheme();
authCache.put(host, authScheme);
context = new BasicHttpContext();
-
context.setAttribute(org.apache.http.client.protocol.HttpClientContext.AUTH_CACHE,
- authCache);
+
context.setAttribute(org.apache.http.client.protocol.HttpClientContext.AUTH_CACHE,
authCache);
CredentialsProvider credentialsProvider = null;
if (clientContext.username() != null && clientContext.password() !=
null) {
credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider
- .setCredentials(new AuthScope(host.getHostName(), host.getPort()),
- new UsernamePasswordCredentials(clientContext.username(),
- clientContext.password()));
+ credentialsProvider.setCredentials(new AuthScope(host.getHostName(),
host.getPort()),
+ new
UsernamePasswordCredentials(clientContext.username(),
+ clientContext.password()));
}
return HttpClients.custom()
- .setConnectionManager(connectionManager)
- .setDefaultCredentialsProvider(credentialsProvider)
- .build();
+ .setConnectionManager(connectionManager)
+ .setDefaultCredentialsProvider(credentialsProvider)
+ .build();
}
}
@@ -457,22 +460,26 @@ public class KnoxSession implements Closeable {
public CloseableHttpResponse executeNow(HttpRequest request ) throws
IOException {
/* check for kerberos */
if (isKerberos) {
- LoginContext lc;
+ Subject subject = Subject.getSubject(AccessController.getContext());
try {
- Configuration jaasConf;
- try {
- jaasConf = new JAASClientConfig(jaasConfigURL);
- } catch (Exception e) {
- LOG.failedToLoadJAASConfiguration(jaasConfigURL.toExternalForm());
- throw new KnoxShellException(e.toString(), e);
- }
+ if (subject == null) {
+ LOG.noSubjectAvailable();
+ Configuration jaasConf;
+ try {
+ jaasConf = new JAASClientConfig(jaasConfigURL);
+ } catch (Exception e) {
+ LOG.failedToLoadJAASConfiguration(jaasConfigURL.toExternalForm());
+ throw new KnoxShellException(e.toString(), e);
+ }
- lc = new LoginContext(JGSS_LOGIN_MOUDLE,
-
Subject.getSubject(AccessController.getContext()),
- new TextCallbackHandler(),
- jaasConf);
- lc.login();
- return Subject.doAs(lc.getSubject(),
+ LoginContext lc = new LoginContext(JGSS_LOGIN_MOUDLE,
+ null,
+ new TextCallbackHandler(),
+ jaasConf);
+ lc.login();
+ subject = lc.getSubject();
+ }
+ return Subject.doAs(subject,
(PrivilegedAction<CloseableHttpResponse>) () -> {
CloseableHttpResponse response;
try {
diff --git
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxShellMessages.java
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxShellMessages.java
index 07f5fa6..16c05bc 100644
---
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxShellMessages.java
+++
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxShellMessages.java
@@ -29,6 +29,9 @@ public interface KnoxShellMessages {
@Message( level = MessageLevel.WARN, text = "Unable to create provided PEM
encoded trusted cert - falling through for other truststores: {0}" )
void unableToLoadProvidedPEMEncodedTrustedCert(@StackTrace( level =
MessageLevel.DEBUG ) IOException e);
+ @Message( level = MessageLevel.DEBUG, text = "No available Subject; Using
JAAS configuration login" )
+ void noSubjectAvailable();
+
@Message( level = MessageLevel.DEBUG, text = "Using JAAS configuration file
implementation: {0}" )
void usingJAASConfigurationFileImplementation(String implName);
diff --git
a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/KnoxSessionTest.java
b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/KnoxSessionTest.java
index 0c275b4..e408ff7 100644
---
a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/KnoxSessionTest.java
+++
b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/KnoxSessionTest.java
@@ -23,8 +23,12 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import org.apache.http.client.methods.CloseableHttpResponse;
import org.junit.Test;
+import javax.security.auth.Subject;
+import java.io.IOException;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Handler;
@@ -98,10 +102,10 @@ public class KnoxSessionTest {
try {
ClientContext context =
ClientContext.with("https://localhost:8443/gateway/dt")
- .kerberos()
- .enable(true)
- .jaasConf(testJaasConf)
- .end();
+ .kerberos()
+ .enable(true)
+ .jaasConf(testJaasConf)
+ .end();
assertNotNull(context);
assertEquals(context.kerberos().jaasConf(), testJaasConf);
@@ -116,6 +120,55 @@ public class KnoxSessionTest {
assertEquals("Using default JAAS configuration",
logCapture.logMessages.get(1));
assertTrue(logCapture.logMessages.get(2).startsWith("JAAS configuration:
"));
assertTrue(logCapture.logMessages.get(2).endsWith("jaas.conf"));
+ assertEquals("No available Subject; Using JAAS configuration login",
logCapture.logMessages.get(3));
+ assertEquals("Using JAAS configuration file implementation:
com.sun.security.auth.login.ConfigFile",
+ logCapture.logMessages.get(4));
+ } finally {
+ logger.removeHandler(logCapture);
+ logger.setLevel(originalLevel);
+ }
+ }
+
+ /**
+ * Validate that JAAS configuration is not applied when a kerberos Subject
is available.
+ * (KNOX-1850)
+ */
+ @Test
+ public void testUseCurrentSubject() {
+ final Logger logger = Logger.getLogger("org.apache.knox.gateway.shell");
+ final Level originalLevel = logger.getLevel();
+ logger.setLevel(Level.FINEST);
+ LogHandler logCapture = new LogHandler();
+ logger.addHandler(logCapture);
+
+ try {
+ ClientContext context =
ClientContext.with("https://localhost:8443/gateway/dt")
+ .kerberos()
+ .enable(true)
+ .end();
+ assertNotNull(context);
+
+ Subject testSubject = new Subject();
+
+ try {
+ KnoxSession session = KnoxSession.login(context);
+ Subject.doAs(testSubject, (PrivilegedAction<CloseableHttpResponse>) ()
-> {
+ try {
+ return session.executeNow(null);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ });
+ } catch (Exception e) {
+ // Expected because the HTTP request is null, which is irrelevant for
this test
+ }
+
+ if(!logCapture.logMessages.isEmpty()) {
+ for (String logMessage : logCapture.logMessages) {
+ assertFalse(logMessage.startsWith("No available Subject"));
+ }
+ }
} finally {
logger.removeHandler(logCapture);
logger.setLevel(originalLevel);