asfgit closed pull request #3256: NIFI-5945 Add support for password login to 
kerberos code in nifi-sec…
URL: https://github.com/apache/nifi/pull/3256
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/StandardKeytabUser.java
 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/AbstractKerberosUser.java
similarity index 86%
rename from 
nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/StandardKeytabUser.java
rename to 
nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/AbstractKerberosUser.java
index 7302ee00eb..32eb9bb3d9 100644
--- 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/StandardKeytabUser.java
+++ 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/AbstractKerberosUser.java
@@ -23,7 +23,6 @@
 import javax.security.auth.Subject;
 import javax.security.auth.kerberos.KerberosPrincipal;
 import javax.security.auth.kerberos.KerberosTicket;
-import javax.security.auth.login.Configuration;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 import java.security.PrivilegedAction;
@@ -34,14 +33,9 @@
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-/**
- * Used to authenticate and execute actions when Kerberos is enabled and a 
keytab is being used.
- *
- * Some of the functionality in this class is adapted from Hadoop's 
UserGroupInformation.
- */
-public class StandardKeytabUser implements KeytabUser {
+public abstract class AbstractKerberosUser implements KerberosUser {
 
-    private static final Logger LOGGER = 
LoggerFactory.getLogger(StandardKeytabUser.class);
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(AbstractKerberosUser.class);
 
     static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
 
@@ -50,18 +44,15 @@
      */
     static final float TICKET_RENEW_WINDOW = 0.80f;
 
-    private final String principal;
-    private final String keytabFile;
-    private final AtomicBoolean loggedIn = new AtomicBoolean(false);
+    protected final String principal;
+    protected final AtomicBoolean loggedIn = new AtomicBoolean(false);
 
-    private Subject subject;
-    private LoginContext loginContext;
+    protected Subject subject;
+    protected LoginContext loginContext;
 
-    public StandardKeytabUser(final String principal, final String keytabFile) 
{
+    public AbstractKerberosUser(final String principal) {
         this.principal = principal;
-        this.keytabFile = keytabFile;
-        Validate.notBlank(principal);
-        Validate.notBlank(keytabFile);
+        Validate.notBlank(this.principal);
     }
 
     /**
@@ -80,19 +71,19 @@ public synchronized void login() throws LoginException {
             if (loginContext == null) {
                 LOGGER.debug("Initializing new login context...");
                 this.subject = new Subject();
-
-                final Configuration config = new 
KeytabConfiguration(principal, keytabFile);
-                this.loginContext = new LoginContext("KeytabConf", subject, 
null, config);
+                this.loginContext = createLoginContext(subject);
             }
 
             loginContext.login();
             loggedIn.set(true);
             LOGGER.debug("Successful login for {}", new Object[]{principal});
         } catch (LoginException le) {
-            throw new LoginException("Unable to login with " + principal + " 
and " + keytabFile + " due to: " + le.getMessage());
+            throw new LoginException("Unable to login with " + principal + " 
due to: " + le.getMessage());
         }
     }
 
+    protected abstract LoginContext createLoginContext(final Subject subject) 
throws LoginException;
+
     /**
      * Performs a logout of the current user.
      *
@@ -244,14 +235,6 @@ public String getPrincipal() {
         return principal;
     }
 
-    /**
-     * @return the keytab file for this user
-     */
-    @Override
-    public String getKeytabFile() {
-        return keytabFile;
-    }
-
     // Visible for testing
     Subject getSubject() {
         return this.subject;
diff --git 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/ConfigurationUtil.java
 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/ConfigurationUtil.java
new file mode 100644
index 0000000000..131ff2233a
--- /dev/null
+++ 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/ConfigurationUtil.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.security.krb;
+
+public interface ConfigurationUtil {
+
+    boolean IS_IBM = System.getProperty("java.vendor", "").contains("IBM");
+    String IBM_KRB5_LOGIN_MODULE = 
"com.ibm.security.auth.module.Krb5LoginModule";
+    String SUN_KRB5_LOGIN_MODULE = 
"com.sun.security.auth.module.Krb5LoginModule";
+
+}
diff --git 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KeytabAction.java
 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosAction.java
similarity index 79%
rename from 
nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KeytabAction.java
rename to 
nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosAction.java
index 5e3f5925fa..bd3e1f9264 100644
--- 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KeytabAction.java
+++ 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosAction.java
@@ -25,24 +25,24 @@
 import java.security.PrivilegedAction;
 
 /**
- * Helper class for processors to perform an action as a KeytabUser.
+ * Helper class for processors to perform an action as a KerberosUser.
  */
-public class KeytabAction {
+public class KerberosAction {
 
-    private final KeytabUser keytabUser;
+    private final KerberosUser kerberosUser;
     private final PrivilegedAction action;
     private final ProcessContext context;
     private final ComponentLog logger;
 
-    public KeytabAction(final KeytabUser keytabUser,
-                        final PrivilegedAction action,
-                        final ProcessContext context,
-                        final ComponentLog logger) {
-        this.keytabUser = keytabUser;
+    public KerberosAction(final KerberosUser kerberosUser,
+                          final PrivilegedAction action,
+                          final ProcessContext context,
+                          final ComponentLog logger) {
+        this.kerberosUser = kerberosUser;
         this.action = action;
         this.context = context;
         this.logger = logger;
-        Validate.notNull(this.keytabUser);
+        Validate.notNull(this.kerberosUser);
         Validate.notNull(this.action);
         Validate.notNull(this.context);
         Validate.notNull(this.logger);
@@ -50,10 +50,10 @@ public KeytabAction(final KeytabUser keytabUser,
 
     public void execute() {
         // lazily login the first time the processor executes
-        if (!keytabUser.isLoggedIn()) {
+        if (!kerberosUser.isLoggedIn()) {
             try {
-                keytabUser.login();
-                logger.info("Successful login for {}", new 
Object[]{keytabUser.getPrincipal()});
+                kerberosUser.login();
+                logger.info("Successful login for {}", new 
Object[]{kerberosUser.getPrincipal()});
             } catch (LoginException e) {
                 // make sure to yield so the processor doesn't keep retrying 
the rolled back flow files immediately
                 context.yield();
@@ -63,7 +63,7 @@ public void execute() {
 
         // check if we need to re-login, will only happen if re-login window 
is reached (80% of TGT life)
         try {
-            keytabUser.checkTGTAndRelogin();
+            kerberosUser.checkTGTAndRelogin();
         } catch (LoginException e) {
             // make sure to yield so the processor doesn't keep retrying the 
rolled back flow files immediately
             context.yield();
@@ -72,15 +72,15 @@ public void execute() {
 
         // attempt to execute the action, if an exception is caught attempt to 
logout/login and retry
         try {
-            keytabUser.doAs(action);
+            kerberosUser.doAs(action);
         } catch (SecurityException se) {
             logger.info("Privileged action failed, attempting relogin and 
retrying...");
             logger.debug("", se);
 
             try {
-                keytabUser.logout();
-                keytabUser.login();
-                keytabUser.doAs(action);
+                kerberosUser.logout();
+                kerberosUser.login();
+                kerberosUser.doAs(action);
             } catch (Exception e) {
                 // make sure to yield so the processor doesn't keep retrying 
the rolled back flow files immediately
                 context.yield();
diff --git 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosKeytabUser.java
 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosKeytabUser.java
new file mode 100644
index 0000000000..a2af82e08a
--- /dev/null
+++ 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosKeytabUser.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.security.krb;
+
+import org.apache.commons.lang3.Validate;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+/**
+ * Used to authenticate and execute actions when Kerberos is enabled and a 
keytab is being used.
+ *
+ * Some of the functionality in this class is adapted from Hadoop's 
UserGroupInformation.
+ */
+public class KerberosKeytabUser extends AbstractKerberosUser {
+
+    private final String keytabFile;
+
+    public KerberosKeytabUser(final String principal, final String keytabFile) 
{
+        super(principal);
+        this.keytabFile = keytabFile;
+        Validate.notBlank(keytabFile);
+    }
+
+    @Override
+    protected LoginContext createLoginContext(Subject subject) throws 
LoginException {
+        final Configuration config = new KeytabConfiguration(principal, 
keytabFile);
+        return new LoginContext("KeytabConf", subject, null, config);
+    }
+
+    /**
+     * @return the keytab file for this user
+     */
+    public String getKeytabFile() {
+        return keytabFile;
+    }
+
+    // Visible for testing
+    Subject getSubject() {
+        return this.subject;
+    }
+
+}
diff --git 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosPasswordUser.java
 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosPasswordUser.java
new file mode 100644
index 0000000000..d81fc850d7
--- /dev/null
+++ 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosPasswordUser.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.security.krb;
+
+import org.apache.commons.lang3.Validate;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * KerberosUser that authenticates via username and password instead of keytab.
+ */
+public class KerberosPasswordUser extends AbstractKerberosUser {
+
+    private final String password;
+
+    public KerberosPasswordUser(final String principal, final String password) 
{
+        super(principal);
+        this.password = password;
+        Validate.notBlank(this.password);
+    }
+
+    @Override
+    protected LoginContext createLoginContext(final Subject subject) throws 
LoginException {
+        final Configuration configuration = new PasswordConfig();
+        final CallbackHandler callbackHandler = new 
UsernamePasswordCallbackHandler(principal, password);
+        return new LoginContext("PasswordConf", subject, callbackHandler, 
configuration);
+    }
+
+    /**
+     * JAAS Configuration to use when logging in with username/password.
+     */
+    private static class PasswordConfig extends Configuration {
+
+        @Override
+        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+            HashMap<String, String> options = new HashMap<String, String>();
+            options.put("storeKey", "true");
+            options.put("refreshKrb5Config", "true");
+
+            final String krbLoginModuleName = ConfigurationUtil.IS_IBM
+                    ? ConfigurationUtil.IBM_KRB5_LOGIN_MODULE : 
ConfigurationUtil.SUN_KRB5_LOGIN_MODULE;
+
+            return new AppConfigurationEntry[] {
+                    new AppConfigurationEntry(
+                            krbLoginModuleName,
+                            
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                            options
+                    )
+            };
+        }
+
+    }
+
+    /**
+     * CallbackHandler that provides the given username and password.
+     */
+    private static class UsernamePasswordCallbackHandler implements 
CallbackHandler {
+
+        private final String username;
+        private final String password;
+
+        public UsernamePasswordCallbackHandler(final String username, final 
String password) {
+            this.username = username;
+            this.password = password;
+            Validate.notBlank(this.username);
+            Validate.notBlank(this.password);
+        }
+
+        public void handle(Callback[] callbacks) throws IOException, 
UnsupportedCallbackException {
+            for (final Callback callback : callbacks) {
+                if (callback instanceof NameCallback) {
+                    final NameCallback nameCallback = (NameCallback) callback;
+                    nameCallback.setName(username);
+                } else if (callback instanceof PasswordCallback) {
+                    final PasswordCallback passwordCallback = 
(PasswordCallback) callback;
+                    passwordCallback.setPassword(password.toCharArray());
+                } else {
+                    throw new IllegalStateException("Unexpected callback type: 
" + callback.getClass().getCanonicalName());
+                }
+            }
+        }
+
+    }
+
+}
diff --git 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KeytabUser.java
 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosUser.java
similarity index 95%
rename from 
nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KeytabUser.java
rename to 
nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosUser.java
index 42089c2d26..16e4fd2b66 100644
--- 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KeytabUser.java
+++ 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KerberosUser.java
@@ -24,7 +24,7 @@
 /**
  * A keytab-based user that can login/logout and perform actions as the given 
user.
  */
-public interface KeytabUser {
+public interface KerberosUser {
 
     /**
      * Performs a login for the given user.
@@ -80,9 +80,4 @@
      */
     String getPrincipal();
 
-    /**
-     * @return the keytab file for this user
-     */
-    String getKeytabFile();
-
 }
diff --git 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KeytabConfiguration.java
 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KeytabConfiguration.java
index 0ad0efe13c..24af9b207e 100644
--- 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KeytabConfiguration.java
+++ 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/krb/KeytabConfiguration.java
@@ -28,10 +28,6 @@
  */
 public class KeytabConfiguration extends Configuration {
 
-    static final boolean IS_IBM = System.getProperty("java.vendor", 
"").contains("IBM");
-    static final String IBM_KRB5_LOGIN_MODULE = 
"com.ibm.security.auth.module.Krb5LoginModule";
-    static final String SUN_KRB5_LOGIN_MODULE = 
"com.sun.security.auth.module.Krb5LoginModule";
-
     private final String principal;
     private final String keytabFile;
 
@@ -53,7 +49,7 @@ public KeytabConfiguration(final String principal, final 
String keytabFile) {
         options.put("principal", principal);
         options.put("refreshKrb5Config", "true");
 
-        if (IS_IBM) {
+        if (ConfigurationUtil.IS_IBM) {
             options.put("useKeytab", keytabFile);
             options.put("credsType", "both");
         } else {
@@ -64,7 +60,8 @@ public KeytabConfiguration(final String principal, final 
String keytabFile) {
             options.put("storeKey", "true");
         }
 
-        final String krbLoginModuleName = IS_IBM ? IBM_KRB5_LOGIN_MODULE : 
SUN_KRB5_LOGIN_MODULE;
+        final String krbLoginModuleName = ConfigurationUtil.IS_IBM
+                ? ConfigurationUtil.IBM_KRB5_LOGIN_MODULE : 
ConfigurationUtil.SUN_KRB5_LOGIN_MODULE;
 
         this.kerberosKeytabConfigEntry = new AppConfigurationEntry(
                 krbLoginModuleName, 
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
diff --git 
a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/KDCServer.java
 
b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/KDCServer.java
index 5669b07be2..478b4dee16 100644
--- 
a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/KDCServer.java
+++ 
b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/KDCServer.java
@@ -67,8 +67,11 @@ public String getRealm() {
         return kdc.getRealm();
     }
 
-    public void createKeytabFile(final File keytabFile, final String... names) 
throws Exception {
+    public void createKeytabPrincipal(final File keytabFile, final String... 
names) throws Exception {
         kdc.createPrincipal(keytabFile, names);
     }
 
+    public void createPasswordPrincipal(final String principal, final String 
password) throws Exception {
+        kdc.createPrincipal(principal, password);
+    }
 }
diff --git 
a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/KeytabUserIT.java
 
b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/KerberosUserIT.java
similarity index 65%
rename from 
nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/KeytabUserIT.java
rename to 
nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/KerberosUserIT.java
index 795f4fb40a..e6360089c4 100644
--- 
a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/KeytabUserIT.java
+++ 
b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/KerberosUserIT.java
@@ -37,7 +37,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.fail;
 
-public class KeytabUserIT {
+public class KerberosUserIT {
 
     @ClassRule
     public static TemporaryFolder tmpDir = new TemporaryFolder();
@@ -50,6 +50,9 @@
     private static KerberosPrincipal principal2;
     private static File principal2KeytabFile;
 
+    private static KerberosPrincipal principal3;
+    private static final String principal3Password = "changeme";
+
     @BeforeClass
     public static void setupClass() throws Exception {
         kdc = new KDCServer(tmpDir.newFolder("mini-kdc_"));
@@ -58,31 +61,34 @@ public static void setupClass() throws Exception {
 
         principal1 = new KerberosPrincipal("user1@" + kdc.getRealm());
         principal1KeytabFile = tmpDir.newFile("user1.keytab");
-        kdc.createKeytabFile(principal1KeytabFile, "user1");
+        kdc.createKeytabPrincipal(principal1KeytabFile, "user1");
 
         principal2 = new KerberosPrincipal("user2@" + kdc.getRealm());
         principal2KeytabFile = tmpDir.newFile("user2.keytab");
-        kdc.createKeytabFile(principal2KeytabFile, "user2");
+        kdc.createKeytabPrincipal(principal2KeytabFile, "user2");
+
+        principal3 = new KerberosPrincipal("user3@" + kdc.getRealm());
+        kdc.createPasswordPrincipal("user3", principal3Password);
     }
 
     @Test
-    public void testSuccessfulLoginAndLogout() throws LoginException {
+    public void testKeytabUserSuccessfulLoginAndLogout() throws LoginException 
{
         // perform login for user1
-        final KeytabUser user1 = new StandardKeytabUser(principal1.getName(), 
principal1KeytabFile.getAbsolutePath());
+        final KerberosUser user1 = new 
KerberosKeytabUser(principal1.getName(), 
principal1KeytabFile.getAbsolutePath());
         user1.login();
 
         // perform login for user2
-        final KeytabUser user2 = new StandardKeytabUser(principal2.getName(), 
principal2KeytabFile.getAbsolutePath());
+        final KerberosUser user2 = new 
KerberosKeytabUser(principal2.getName(), 
principal2KeytabFile.getAbsolutePath());
         user2.login();
 
         // verify user1 Subject only has user1 principal
-        final Subject user1Subject = ((StandardKeytabUser) user1).getSubject();
+        final Subject user1Subject = ((KerberosKeytabUser) user1).getSubject();
         final Set<Principal> user1SubjectPrincipals = 
user1Subject.getPrincipals();
         assertEquals(1, user1SubjectPrincipals.size());
         assertEquals(principal1.getName(), 
user1SubjectPrincipals.iterator().next().getName());
 
         // verify user2 Subject only has user2 principal
-        final Subject user2Subject = ((StandardKeytabUser) user2).getSubject();
+        final Subject user2Subject = ((KerberosKeytabUser) user2).getSubject();
         final Set<Principal> user2SubjectPrincipals = 
user2Subject.getPrincipals();
         assertEquals(1, user2SubjectPrincipals.size());
         assertEquals(principal2.getName(), 
user2SubjectPrincipals.iterator().next().getName());
@@ -101,9 +107,9 @@ public void testSuccessfulLoginAndLogout() throws 
LoginException {
     }
 
     @Test
-    public void testLoginWithUnknownPrincipal() throws LoginException {
+    public void testKeytabLoginWithUnknownPrincipal() throws LoginException {
         final String unknownPrincipal = "doesnotexist@" + kdc.getRealm();
-        final KeytabUser user1 = new StandardKeytabUser(unknownPrincipal, 
principal1KeytabFile.getAbsolutePath());
+        final KerberosUser user1 = new KerberosKeytabUser(unknownPrincipal, 
principal1KeytabFile.getAbsolutePath());
         try {
             user1.login();
             fail("Login should have failed");
@@ -113,9 +119,38 @@ public void testLoginWithUnknownPrincipal() throws 
LoginException {
         }
     }
 
+    @Test
+    public void testPasswordUserSuccessfulLoginAndLogout() throws 
LoginException {
+        // perform login for user
+        final KerberosUser user = new 
KerberosPasswordUser(principal3.getName(), principal3Password);
+        user.login();
+
+        // verify user Subject only has user principal
+        final Subject userSubject = ((KerberosPasswordUser) user).getSubject();
+        final Set<Principal> userSubjectPrincipals = 
userSubject.getPrincipals();
+        assertEquals(1, userSubjectPrincipals.size());
+        assertEquals(principal3.getName(), 
userSubjectPrincipals.iterator().next().getName());
+
+        // call check/relogin and verify neither user performed a relogin
+        assertFalse(user.checkTGTAndRelogin());
+
+        // perform logout for both users
+        user.logout();
+
+        // verify subjects have no more principals
+        assertEquals(0, userSubject.getPrincipals().size());
+    }
+
+    @Test(expected = LoginException.class)
+    public void testPasswordUserLoginWithInvalidPassword() throws 
LoginException {
+        // perform login for user
+        final KerberosUser user = new KerberosPasswordUser("user3", "NOT THE 
PASSWORD");
+        user.login();
+    }
+
     @Test
     public void testCheckTGTAndRelogin() throws LoginException, 
InterruptedException {
-        final KeytabUser user1 = new StandardKeytabUser(principal1.getName(), 
principal1KeytabFile.getAbsolutePath());
+        final KerberosUser user1 = new 
KerberosKeytabUser(principal1.getName(), 
principal1KeytabFile.getAbsolutePath());
         user1.login();
 
         // Since we set the lifetime to 15 seconds we should hit a relogin 
before 15 attempts
@@ -136,7 +171,7 @@ public void testCheckTGTAndRelogin() throws LoginException, 
InterruptedException
 
     @Test
     public void testKeytabAction() {
-        final KeytabUser user1 = new StandardKeytabUser(principal1.getName(), 
principal1KeytabFile.getAbsolutePath());
+        final KerberosUser user1 = new 
KerberosKeytabUser(principal1.getName(), 
principal1KeytabFile.getAbsolutePath());
 
         final AtomicReference<String> resultHolder = new 
AtomicReference<>(null);
         final PrivilegedAction privilegedAction = () -> {
@@ -148,8 +183,8 @@ public void testKeytabAction() {
         final ComponentLog logger = Mockito.mock(ComponentLog.class);
 
         // create the action to test and execute it
-        final KeytabAction keytabAction = new KeytabAction(user1, 
privilegedAction, context, logger);
-        keytabAction.execute();
+        final KerberosAction kerberosAction = new KerberosAction(user1, 
privilegedAction, context, logger);
+        kerberosAction.execute();
 
         // if the result holder has the string success then we know the action 
executed
         assertEquals("SUCCESS", resultHolder.get());
diff --git 
a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/TestKeytabConfiguration.java
 
b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/TestKeytabConfiguration.java
index f1056365c1..663fa06329 100644
--- 
a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/TestKeytabConfiguration.java
+++ 
b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/krb/TestKeytabConfiguration.java
@@ -39,7 +39,7 @@ public void testCreatingKeytabConfiguration() {
         assertEquals(1, entries.length);
 
         final AppConfigurationEntry entry = entries[0];
-        assertEquals(KeytabConfiguration.SUN_KRB5_LOGIN_MODULE, 
entry.getLoginModuleName());
+        assertEquals(ConfigurationUtil.SUN_KRB5_LOGIN_MODULE, 
entry.getLoginModuleName());
         assertEquals(principal, entry.getOptions().get("principal"));
         assertEquals(keytab, entry.getOptions().get("keyTab"));
     }
diff --git 
a/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/src/main/java/org/apache/nifi/processors/solr/SolrProcessor.java
 
b/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/src/main/java/org/apache/nifi/processors/solr/SolrProcessor.java
index fa44b2e604..4a193b62ff 100755
--- 
a/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/src/main/java/org/apache/nifi/processors/solr/SolrProcessor.java
+++ 
b/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/src/main/java/org/apache/nifi/processors/solr/SolrProcessor.java
@@ -28,9 +28,9 @@
 import org.apache.nifi.processor.ProcessContext;
 import org.apache.nifi.processor.ProcessSession;
 import org.apache.nifi.processor.exception.ProcessException;
-import org.apache.nifi.security.krb.KeytabAction;
-import org.apache.nifi.security.krb.KeytabUser;
-import org.apache.nifi.security.krb.StandardKeytabUser;
+import org.apache.nifi.security.krb.KerberosAction;
+import org.apache.nifi.security.krb.KerberosUser;
+import org.apache.nifi.security.krb.KerberosKeytabUser;
 import org.apache.nifi.ssl.SSLContextService;
 import org.apache.solr.client.solrj.SolrClient;
 
@@ -63,7 +63,7 @@
     private volatile String basicPassword;
     private volatile boolean basicAuthEnabled = false;
 
-    private volatile KeytabUser keytabUser;
+    private volatile KerberosUser kerberosUser;
 
     @OnScheduled
     public final void onScheduled(final ProcessContext context) throws 
IOException {
@@ -78,12 +78,12 @@ public final void onScheduled(final ProcessContext context) 
throws IOException {
 
         final KerberosCredentialsService kerberosCredentialsService = 
context.getProperty(KERBEROS_CREDENTIALS_SERVICE).asControllerService(KerberosCredentialsService.class);
         if (kerberosCredentialsService != null) {
-            this.keytabUser = createKeytabUser(kerberosCredentialsService);
+            this.kerberosUser = createKeytabUser(kerberosCredentialsService);
         }
     }
 
-    protected KeytabUser createKeytabUser(final KerberosCredentialsService 
kerberosCredentialsService) {
-        return new 
StandardKeytabUser(kerberosCredentialsService.getPrincipal(), 
kerberosCredentialsService.getKeytab());
+    protected KerberosUser createKeytabUser(final KerberosCredentialsService 
kerberosCredentialsService) {
+        return new 
KerberosKeytabUser(kerberosCredentialsService.getPrincipal(), 
kerberosCredentialsService.getKeytab());
     }
 
     @OnStopped
@@ -96,10 +96,10 @@ public final void closeClient() {
             }
         }
 
-        if (keytabUser != null) {
+        if (kerberosUser != null) {
             try {
-                keytabUser.logout();
-                keytabUser = null;
+                kerberosUser.logout();
+                kerberosUser = null;
             } catch (LoginException e) {
                 getLogger().debug("Error logging out keytab user", e);
             }
@@ -108,8 +108,8 @@ public final void closeClient() {
 
     @Override
     public final void onTrigger(final ProcessContext context, final 
ProcessSession session) throws ProcessException {
-        final KeytabUser keytabUser = getKerberosKeytabUser();
-        if (keytabUser == null) {
+        final KerberosUser kerberosUser = getKerberosKeytabUser();
+        if (kerberosUser == null) {
             doOnTrigger(context, session);
         } else {
             // wrap doOnTrigger in a privileged action
@@ -119,8 +119,8 @@ public final void onTrigger(final ProcessContext context, 
final ProcessSession s
             };
 
             // execute the privileged action as the given keytab user
-            final KeytabAction keytabAction = new KeytabAction(keytabUser, 
action, context, getLogger());
-            keytabAction.execute();
+            final KerberosAction kerberosAction = new 
KerberosAction(kerberosUser, action, context, getLogger());
+            kerberosAction.execute();
         }
     }
 
@@ -168,8 +168,8 @@ protected final boolean isBasicAuthEnabled() {
         return basicAuthEnabled;
     }
 
-    protected final KeytabUser getKerberosKeytabUser() {
-        return keytabUser;
+    protected final KerberosUser getKerberosKeytabUser() {
+        return kerberosUser;
     }
 
     @Override
diff --git 
a/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/src/test/java/org/apache/nifi/processors/solr/TestPutSolrContentStream.java
 
b/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/src/test/java/org/apache/nifi/processors/solr/TestPutSolrContentStream.java
index 4eeb12a524..e3c3b796b7 100755
--- 
a/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/src/test/java/org/apache/nifi/processors/solr/TestPutSolrContentStream.java
+++ 
b/nifi-nar-bundles/nifi-solr-bundle/nifi-solr-processors/src/test/java/org/apache/nifi/processors/solr/TestPutSolrContentStream.java
@@ -21,7 +21,8 @@
 import org.apache.nifi.processor.ProcessContext;
 import org.apache.nifi.processor.exception.ProcessException;
 import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.security.krb.KeytabUser;
+import org.apache.nifi.security.krb.KerberosKeytabUser;
+import org.apache.nifi.security.krb.KerberosUser;
 import org.apache.nifi.ssl.SSLContextService;
 import org.apache.nifi.util.TestRunner;
 import org.apache.nifi.util.TestRunners;
@@ -451,10 +452,10 @@ public void testBasicAuthAndKerberosNotAllowedTogether() 
throws IOException, Ini
         runner.assertValid();
 
         proc.onScheduled(runner.getProcessContext());
-        final KeytabUser keytabUser = proc.getMockKerberosKeytabUser();
-        Assert.assertNotNull(keytabUser);
-        Assert.assertEquals(principal, keytabUser.getPrincipal());
-        Assert.assertEquals(keytab, keytabUser.getKeytabFile());
+        final KerberosUser kerberosUser = proc.getMockKerberosKeytabUser();;
+        Assert.assertNotNull(kerberosUser);
+        Assert.assertEquals(principal, kerberosUser.getPrincipal());
+        Assert.assertEquals(keytab, 
((KerberosKeytabUser)kerberosUser).getKeytabFile());
     }
 
     @Test
@@ -462,20 +463,20 @@ public void testUpdateWithKerberosAuth() throws 
IOException, InitializationExcep
         final String principal = "n...@foo.com";
         final String keytab = "src/test/resources/foo.keytab";
 
-        // Setup a mock KeytabUser that will still execute the privileged 
action
-        final KeytabUser keytabUser = Mockito.mock(KeytabUser.class);
-        when(keytabUser.getPrincipal()).thenReturn(principal);
-        when(keytabUser.getKeytabFile()).thenReturn(keytab);
-        
when(keytabUser.doAs(any(PrivilegedAction.class))).thenAnswer((invocation -> {
+        // Setup a mock KerberosUser that will still execute the privileged 
action
+        final KerberosKeytabUser kerberosUser = 
Mockito.mock(KerberosKeytabUser.class);
+        when(kerberosUser.getPrincipal()).thenReturn(principal);
+        when(kerberosUser.getKeytabFile()).thenReturn(keytab);
+        
when(kerberosUser.doAs(any(PrivilegedAction.class))).thenAnswer((invocation -> {
                     final PrivilegedAction action = (PrivilegedAction) 
invocation.getArguments()[0];
                     action.run();
                     return null;
                 })
         );
 
-        // Configure the processor with the mock KeytabUser and with a 
credentials service
+        // Configure the processor with the mock KerberosUser and with a 
credentials service
         final SolrClient solrClient = 
createEmbeddedSolrClient(DEFAULT_SOLR_CORE);
-        final TestableProcessor proc = new TestableProcessor(solrClient, 
keytabUser);
+        final TestableProcessor proc = new TestableProcessor(solrClient, 
kerberosUser);
         final TestRunner runner = createDefaultTestRunner(proc);
 
         final KerberosCredentialsService kerberosCredentialsService = new 
MockKerberosCredentialsService(principal, keytab);
@@ -499,9 +500,9 @@ public void testUpdateWithKerberosAuth() throws 
IOException, InitializationExcep
         }
 
         // Verify that during the update the user was logged in, TGT was 
checked, and the action was executed
-        verify(keytabUser, times(1)).login();
-        verify(keytabUser, times(1)).checkTGTAndRelogin();
-        verify(keytabUser, times(1)).doAs(any(PrivilegedAction.class));
+        verify(kerberosUser, times(1)).login();
+        verify(kerberosUser, times(1)).checkTGTAndRelogin();
+        verify(kerberosUser, times(1)).doAs(any(PrivilegedAction.class));
     }
 
 
@@ -647,15 +648,15 @@ protected SolrClient createSolrClient(ProcessContext 
context, String solrLocatio
     // Override createSolrClient and return the passed in SolrClient
     private class TestableProcessor extends PutSolrContentStream {
         private SolrClient solrClient;
-        private KeytabUser keytabUser;
+        private KerberosUser kerberosUser;
 
         public TestableProcessor(SolrClient solrClient) {
             this.solrClient = solrClient;
         }
 
-        public TestableProcessor(SolrClient solrClient, KeytabUser keytabUser) 
{
+        public TestableProcessor(SolrClient solrClient, KerberosUser 
kerberosUser) {
             this.solrClient = solrClient;
-            this.keytabUser = keytabUser;
+            this.kerberosUser = kerberosUser;
         }
 
         @Override
@@ -664,15 +665,15 @@ protected SolrClient createSolrClient(ProcessContext 
context, String solrLocatio
         }
 
         @Override
-        protected KeytabUser createKeytabUser(KerberosCredentialsService 
kerberosCredentialsService) {
-            if (keytabUser != null) {
-                return keytabUser;
+        protected KerberosUser createKeytabUser(KerberosCredentialsService 
kerberosCredentialsService) {
+            if (kerberosUser != null) {
+                return kerberosUser;
             } else {
                 return super.createKeytabUser(kerberosCredentialsService);
             }
         }
 
-        public KeytabUser getMockKerberosKeytabUser() {
+        public KerberosUser getMockKerberosKeytabUser() {
             return super.getKerberosKeytabUser();
         }
     }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to