diff --git a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
index d381f740a8..4a7e5d8c57 100644
--- a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
+++ b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
@@ -179,8 +179,10 @@ public abstract class NiFiProperties {
// kerberos properties
public static final String KERBEROS_KRB5_FILE = "nifi.kerberos.krb5.file";
public static final String KERBEROS_SERVICE_PRINCIPAL = "nifi.kerberos.service.principal";
- public static final String KERBEROS_KEYTAB_LOCATION = "nifi.kerberos.keytab.location";
- public static final String KERBEROS_AUTHENTICATION_EXPIRATION = "nifi.kerberos.authentication.expiration";
+ public static final String KERBEROS_SERVICE_KEYTAB_LOCATION = "nifi.kerberos.service.keytab.location";
+ public static final String KERBEROS_SPNEGO_PRINCIPAL = "nifi.kerberos.spnego.principal";
+ public static final String KERBEROS_SPNEGO_KEYTAB_LOCATION = "nifi.kerberos.spnego.keytab.location";
+ public static final String KERBEROS_AUTHENTICATION_EXPIRATION = "nifi.kerberos.spnego.authentication.expiration";
// state management
public static final String STATE_MANAGEMENT_CONFIG_FILE = "nifi.state.management.configuration.file";
@@ -717,8 +719,26 @@ public abstract class NiFiProperties {
}
}
- public String getKerberosKeytabLocation() {
- final String keytabLocation = getProperty(KERBEROS_KEYTAB_LOCATION);
+ public String getKerberosServiceKeytabLocation() {
+ final String keytabLocation = getProperty(KERBEROS_SERVICE_KEYTAB_LOCATION);
+ if (!StringUtils.isBlank(keytabLocation)) {
+ return keytabLocation.trim();
+ } else {
+ return null;
+ }
+ }
+
+ public String getKerberosSpnegoPrincipal() {
+ final String spengoPrincipal = getProperty(KERBEROS_SPNEGO_PRINCIPAL);
+ if (!StringUtils.isBlank(spengoPrincipal)) {
+ return spengoPrincipal.trim();
+ } else {
+ return null;
+ }
+ }
+
+ public String getKerberosSpnegoKeytabLocation() {
+ final String keytabLocation = getProperty(KERBEROS_SPNEGO_KEYTAB_LOCATION);
if (!StringUtils.isBlank(keytabLocation)) {
return keytabLocation.trim();
} else {
@@ -741,8 +761,8 @@ public abstract class NiFiProperties {
*
* @return true if Kerberos service support is enabled
*/
- public boolean isKerberosServiceSupportEnabled() {
- return !StringUtils.isBlank(getKerberosServicePrincipal()) && !StringUtils.isBlank(getKerberosKeytabLocation());
+ public boolean isKerberosSpnegoSupportEnabled() {
+ return !StringUtils.isBlank(getKerberosSpnegoPrincipal()) && !StringUtils.isBlank(getKerberosSpnegoKeytabLocation());
}
/**
@@ -756,7 +776,7 @@ public abstract class NiFiProperties {
* API
*/
public boolean isClientAuthRequiredForRestApi() {
- return StringUtils.isBlank(getProperty(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER)) && !isKerberosServiceSupportEnabled();
+ return StringUtils.isBlank(getProperty(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER)) && !isKerberosSpnegoSupportEnabled();
}
public InetSocketAddress getNodeApiAddress() {
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index b0a96de985..65e98456ec 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -1903,15 +1903,19 @@ that is specified.
|====
|*Property*|*Description*
-|nifi.kerberos.krb5.file*|The location of the krb5 file, if used. It is blank by default. Note that this property is not used to authenticate NiFi users.
- Rather, it is made available for extension points, such as Hadoop-based Processors, to use. At this time, only a single krb5 file is allowed to
- be specified per NiFi instance, so this property is configured here rather than in individual Processors.
+|nifi.kerberos.krb5.file*|The location of the krb5 file, if used. It is blank by default. At this time, only a single krb5 file is allowed to
+ be specified per NiFi instance, so this property is configured here to support SPNEGO and service principles rather than in individual Processors.
+ If necessary the krb5 file can support multiple realms.
Example: `/etc/krb5.conf`
-|nifi.kerberos.service.principal*|The name of the NiFi Kerberos service principal, if used. It is blank by default. Note that this property is used to authenticate NiFi users.
+|nifi.kerberos.service.principal*|The name of the NiFi Kerberos service principal, if used. It is blank by default. Note that this property is for NiFi to authenticate as a client other systems.
+ Example: `nifi/nifi.example.com` or `nifi/nifi.example.com@EXAMPLE.COM`
+|nifi.kerberos.service.keytab.location*|The file path of the NiFi Kerberos keytab, if used. It is blank by default. Note that this property is for NiFi to authenticate as a client other systems.
+ Example: `/etc/nifi.keytab`
+|nifi.kerberos.spnego.principal*|The name of the NiFi Kerberos service principal, if used. It is blank by default. Note that this property is used to authenticate NiFi users.
Example: `HTTP/nifi.example.com` or `HTTP/nifi.example.com@EXAMPLE.COM`
-|nifi.kerberos.keytab.location*|The file path of the NiFi Kerberos keytab, if used. It is blank by default. Note that this property is used to authenticate NiFi users.
+|nifi.kerberos.spnego.keytab.location*|The file path of the NiFi Kerberos keytab, if used. It is blank by default. Note that this property is used to authenticate NiFi users.
Example: `/etc/http-nifi.keytab`
-|nifi.kerberos.authentication.expiration*|The expiration duration of a successful Kerberos user authentication, if used. It is 12 hours by default.
+|nifi.kerberos.spengo.authentication.expiration*|The expiration duration of a successful Kerberos user authentication, if used. It is 12 hours by default.
Example: `12 hours`
|====
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
index fff546b87e..e367e2af14 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
@@ -161,8 +161,10 @@
-
- 12 hours
+
+
+
+ 12 hours
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
index a65b26570a..485b60e494 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
@@ -179,9 +179,15 @@ nifi.zookeeper.root.node=${nifi.zookeeper.root.node}
# kerberos #
nifi.kerberos.krb5.file=${nifi.kerberos.krb5.file}
+
+# kerberos service principle #
nifi.kerberos.service.principal=${nifi.kerberos.service.principal}
-nifi.kerberos.keytab.location=${nifi.kerberos.keytab.location}
-nifi.kerberos.authentication.expiration=${nifi.kerberos.authentication.expiration}
+nifi.kerberos.service.keytab.location=${nifi.kerberos.service.keytab.location}
+
+# kerberos spnego principle #
+nifi.kerberos.spnego.principal=${nifi.kerberos.spnego.principal}
+nifi.kerberos.spnego.keytab.location=${nifi.kerberos.spnego.keytab.location}
+nifi.kerberos.spnego.authentication.expiration=${nifi.kerberos.spnego.authentication.expiration}
# external properties files for variable registry
# supports a comma delimited list of file locations
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
index 6ced1c09a3..5c108a49ac 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
@@ -345,7 +345,7 @@ public class AccessResource extends ApplicationResource {
}
// If Kerberos Service Principal and keytab location not configured, throws exception
- if (!properties.isKerberosServiceSupportEnabled() || kerberosService == null) {
+ if (!properties.isKerberosSpnegoSupportEnabled() || kerberosService == null) {
throw new IllegalStateException("Kerberos ticket login not supported by this NiFi.");
}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/site-to-site/nifi.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/site-to-site/nifi.properties
index 3d7d0e8b3f..4800770728 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/site-to-site/nifi.properties
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/site-to-site/nifi.properties
@@ -170,5 +170,7 @@ nifi.zookeeper.root.node=${nifi.zookeeper.root.node}
# kerberos #
nifi.kerberos.krb5.file=${nifi.kerberos.krb5.file}
nifi.kerberos.service.principal=${nifi.kerberos.service.principal}
-nifi.kerberos.keytab.location=${nifi.kerberos.keytab.location}
-nifi.kerberos.authentication.expiration=${nifi.kerberos.authentication.expiration}
\ No newline at end of file
+nifi.kerberos.service.keytab.location=${nifi.kerberos.service.keytab.location}
+nifi.kerberos.spnego.principal=${nifi.kerberos.spnego.principal}
+nifi.kerberos.spnego.keytab.location=${nifi.kerberos.spnego.keytab.location}
+nifi.kerberos.spnego.authentication.expiration=${nifi.kerberos.spnego.authentication.expiration}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/KerberosServiceFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/KerberosServiceFactoryBean.java
index bbe15d120e..3ea7f5df50 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/KerberosServiceFactoryBean.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/KerberosServiceFactoryBean.java
@@ -23,8 +23,11 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.core.io.FileSystemResource;
import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider;
import org.springframework.security.kerberos.authentication.KerberosTicketValidator;
+import org.springframework.security.kerberos.authentication.sun.GlobalSunJaasKerberosConfig;
import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator;
+import java.io.File;
+
public class KerberosServiceFactoryBean implements FactoryBean {
private KerberosService kerberosService = null;
@@ -32,7 +35,14 @@ public class KerberosServiceFactoryBean implements FactoryBean
@Override
public KerberosService getObject() throws Exception {
- if (kerberosService == null && properties.isKerberosServiceSupportEnabled()) {
+ if (kerberosService == null && properties.isKerberosSpnegoSupportEnabled()) {
+ final File krb5ConfigFile = properties.getKerberosConfigurationFile();
+ if (krb5ConfigFile != null) {
+ final GlobalSunJaasKerberosConfig krb5Config = new GlobalSunJaasKerberosConfig();
+ krb5Config.setKrbConfLocation(krb5ConfigFile.getAbsolutePath());
+ krb5Config.afterPropertiesSet();
+ }
+
kerberosService = new KerberosService();
kerberosService.setKerberosServiceAuthenticationProvider(createKerberosServiceAuthenticationProvider());
}
@@ -68,8 +78,8 @@ public class KerberosServiceFactoryBean implements FactoryBean
private KerberosTicketValidator createTicketValidator() throws Exception {
SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
- ticketValidator.setServicePrincipal(properties.getKerberosServicePrincipal());
- ticketValidator.setKeyTabLocation(new FileSystemResource(properties.getKerberosKeytabLocation()));
+ ticketValidator.setServicePrincipal(properties.getKerberosSpnegoPrincipal());
+ ticketValidator.setKeyTabLocation(new FileSystemResource(properties.getKerberosSpnegoKeytabLocation()));
ticketValidator.afterPropertiesSet();
return ticketValidator;
}
diff --git a/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers/src/main/java/org/apache/nifi/kerberos/KerberosProvider.java b/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers/src/main/java/org/apache/nifi/kerberos/KerberosProvider.java
index f9856020af..1b35514de1 100644
--- a/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers/src/main/java/org/apache/nifi/kerberos/KerberosProvider.java
+++ b/nifi-nar-bundles/nifi-kerberos-iaa-providers-bundle/nifi-kerberos-iaa-providers/src/main/java/org/apache/nifi/kerberos/KerberosProvider.java
@@ -33,6 +33,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider;
+import org.springframework.security.kerberos.authentication.sun.GlobalSunJaasKerberosConfig;
import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient;
import java.util.concurrent.TimeUnit;
@@ -66,6 +67,17 @@ public class KerberosProvider implements LoginIdentityProvider {
throw new ProviderCreationException(String.format("The Expiration Duration '%s' is not a valid time duration", rawExpiration));
}
+ try {
+ final String krb5ConfigFile = configurationContext.getProperty("Kerberos Config File");
+ if (StringUtils.isNotEmpty(krb5ConfigFile)) {
+ final GlobalSunJaasKerberosConfig krb5Config = new GlobalSunJaasKerberosConfig();
+ krb5Config.setKrbConfLocation(krb5ConfigFile);
+ krb5Config.afterPropertiesSet();
+ }
+ } catch (final Exception e) {
+ throw new ProviderCreationException(e.getMessage(), e);
+ }
+
provider = new KerberosAuthenticationProvider();
SunJaasKerberosClient client = new SunJaasKerberosClient();
client.setDebug(true);
diff --git a/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/RangerNiFiAuthorizer.java b/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/RangerNiFiAuthorizer.java
index ab31fa3f29..a86423cc82 100644
--- a/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/RangerNiFiAuthorizer.java
+++ b/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/RangerNiFiAuthorizer.java
@@ -102,7 +102,7 @@ public class RangerNiFiAuthorizer implements Authorizer {
// login with the nifi principal and keytab, RangerAdminRESTClient will use Ranger's MiscUtil which
// will grab UserGroupInformation.getLoginUser() and call ugi.checkTGTAndReloginFromKeytab();
final String nifiPrincipal = nifiProperties.getKerberosServicePrincipal();
- final String nifiKeytab = nifiProperties.getKerberosKeytabLocation();
+ final String nifiKeytab = nifiProperties.getKerberosServiceKeytabLocation();
if (StringUtils.isBlank(nifiPrincipal) || StringUtils.isBlank(nifiKeytab)) {
throw new AuthorizerCreationException("Principal and Keytab must be provided when Kerberos is enabled");
diff --git a/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/test/java/org/apache/nifi/ranger/authorization/TestRangerNiFiAuthorizer.java b/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/test/java/org/apache/nifi/ranger/authorization/TestRangerNiFiAuthorizer.java
index af5012503b..1bfa1b3fcf 100644
--- a/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/test/java/org/apache/nifi/ranger/authorization/TestRangerNiFiAuthorizer.java
+++ b/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/test/java/org/apache/nifi/ranger/authorization/TestRangerNiFiAuthorizer.java
@@ -149,7 +149,7 @@ public class TestRangerNiFiAuthorizer {
.thenReturn(new MockPropertyValue("true"));
nifiProperties = Mockito.mock(NiFiProperties.class);
- when(nifiProperties.getKerberosKeytabLocation()).thenReturn("");
+ when(nifiProperties.getKerberosServiceKeytabLocation()).thenReturn("");
authorizer = new MockRangerNiFiAuthorizer(rangerBasePlugin);
authorizer.setNiFiProperties(nifiProperties);
@@ -169,7 +169,7 @@ public class TestRangerNiFiAuthorizer {
.thenReturn(new MockPropertyValue("true"));
nifiProperties = Mockito.mock(NiFiProperties.class);
- when(nifiProperties.getKerberosKeytabLocation()).thenReturn("");
+ when(nifiProperties.getKerberosServiceKeytabLocation()).thenReturn("");
when(nifiProperties.getKerberosServicePrincipal()).thenReturn("");
authorizer = new MockRangerNiFiAuthorizer(rangerBasePlugin);
@@ -203,7 +203,7 @@ public class TestRangerNiFiAuthorizer {
.thenReturn(new MockPropertyValue("true"));
nifiProperties = Mockito.mock(NiFiProperties.class);
- when(nifiProperties.getKerberosKeytabLocation()).thenReturn("test");
+ when(nifiProperties.getKerberosServiceKeytabLocation()).thenReturn("test");
when(nifiProperties.getKerberosServicePrincipal()).thenReturn("test");
authorizer = new MockRangerNiFiAuthorizer(rangerBasePlugin);
diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/localhost/nifi.properties b/nifi-toolkit/nifi-toolkit-tls/src/test/resources/localhost/nifi.properties
index 41b091c8ab..deda7f9abf 100644
--- a/nifi-toolkit/nifi-toolkit-tls/src/test/resources/localhost/nifi.properties
+++ b/nifi-toolkit/nifi-toolkit-tls/src/test/resources/localhost/nifi.properties
@@ -173,5 +173,8 @@ nifi.zookeeper.root.node=/nifi
# kerberos #
nifi.kerberos.krb5.file=
nifi.kerberos.service.principal=
-nifi.kerberos.keytab.location=
-nifi.kerberos.authentication.expiration=12 hours
+nifi.kerberos.service.keytab.location=
+
+nifi.kerberos.spnego.principal=
+nifi.kerberos.spnego.keytab.location=
+nifi.kerberos.spnego.authentication.expiration=12 hours
\ No newline at end of file