NIFI-2574 merging latest kerb changes to adjust for NiFiProperties

This commit is contained in:
joewitt 2016-08-17 09:06:18 -07:00
commit a5261914fb
11 changed files with 88 additions and 29 deletions

View File

@ -179,8 +179,10 @@ public abstract class NiFiProperties {
// kerberos properties // kerberos properties
public static final String KERBEROS_KRB5_FILE = "nifi.kerberos.krb5.file"; 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_SERVICE_PRINCIPAL = "nifi.kerberos.service.principal";
public static final String KERBEROS_KEYTAB_LOCATION = "nifi.kerberos.keytab.location"; public static final String KERBEROS_SERVICE_KEYTAB_LOCATION = "nifi.kerberos.service.keytab.location";
public static final String KERBEROS_AUTHENTICATION_EXPIRATION = "nifi.kerberos.authentication.expiration"; 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 // state management
public static final String STATE_MANAGEMENT_CONFIG_FILE = "nifi.state.management.configuration.file"; public static final String STATE_MANAGEMENT_CONFIG_FILE = "nifi.state.management.configuration.file";
@ -717,8 +719,26 @@ public abstract class NiFiProperties {
} }
} }
public String getKerberosKeytabLocation() { public String getKerberosServiceKeytabLocation() {
final String keytabLocation = getProperty(KERBEROS_KEYTAB_LOCATION); 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)) { if (!StringUtils.isBlank(keytabLocation)) {
return keytabLocation.trim(); return keytabLocation.trim();
} else { } else {
@ -741,8 +761,8 @@ public abstract class NiFiProperties {
* *
* @return true if Kerberos service support is enabled * @return true if Kerberos service support is enabled
*/ */
public boolean isKerberosServiceSupportEnabled() { public boolean isKerberosSpnegoSupportEnabled() {
return !StringUtils.isBlank(getKerberosServicePrincipal()) && !StringUtils.isBlank(getKerberosKeytabLocation()); return !StringUtils.isBlank(getKerberosSpnegoPrincipal()) && !StringUtils.isBlank(getKerberosSpnegoKeytabLocation());
} }
/** /**
@ -756,7 +776,7 @@ public abstract class NiFiProperties {
* API * API
*/ */
public boolean isClientAuthRequiredForRestApi() { 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() { public InetSocketAddress getNodeApiAddress() {

View File

@ -1903,15 +1903,19 @@ that is specified.
|==== |====
|*Property*|*Description* |*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. |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
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 to support SPNEGO and service principles rather than in individual Processors.
be specified per NiFi instance, so this property is configured here rather than in individual Processors. If necessary the krb5 file can support multiple realms.
Example: `/etc/krb5.conf` 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` 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` 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` Example: `12 hours`
|==== |====

View File

@ -161,8 +161,10 @@
<!-- nifi.properties: kerberos properties --> <!-- nifi.properties: kerberos properties -->
<nifi.kerberos.krb5.file> </nifi.kerberos.krb5.file> <nifi.kerberos.krb5.file> </nifi.kerberos.krb5.file>
<nifi.kerberos.service.principal /> <nifi.kerberos.service.principal />
<nifi.kerberos.keytab.location /> <nifi.kerberos.service.keytab.location />
<nifi.kerberos.authentication.expiration>12 hours</nifi.kerberos.authentication.expiration> <nifi.kerberos.spnego.principal />
<nifi.kerberos.spnego.keytab.location />
<nifi.kerberos.spnego.authentication.expiration>12 hours</nifi.kerberos.spnego.authentication.expiration>
</properties> </properties>
<build> <build>
<plugins> <plugins>

View File

@ -179,9 +179,15 @@ nifi.zookeeper.root.node=${nifi.zookeeper.root.node}
# kerberos # # kerberos #
nifi.kerberos.krb5.file=${nifi.kerberos.krb5.file} nifi.kerberos.krb5.file=${nifi.kerberos.krb5.file}
# kerberos service principle #
nifi.kerberos.service.principal=${nifi.kerberos.service.principal} nifi.kerberos.service.principal=${nifi.kerberos.service.principal}
nifi.kerberos.keytab.location=${nifi.kerberos.keytab.location} nifi.kerberos.service.keytab.location=${nifi.kerberos.service.keytab.location}
nifi.kerberos.authentication.expiration=${nifi.kerberos.authentication.expiration}
# 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 # external properties files for variable registry
# supports a comma delimited list of file locations # supports a comma delimited list of file locations

View File

@ -345,7 +345,7 @@ public class AccessResource extends ApplicationResource {
} }
// If Kerberos Service Principal and keytab location not configured, throws exception // 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."); throw new IllegalStateException("Kerberos ticket login not supported by this NiFi.");
} }

View File

@ -170,5 +170,7 @@ nifi.zookeeper.root.node=${nifi.zookeeper.root.node}
# kerberos # # kerberos #
nifi.kerberos.krb5.file=${nifi.kerberos.krb5.file} nifi.kerberos.krb5.file=${nifi.kerberos.krb5.file}
nifi.kerberos.service.principal=${nifi.kerberos.service.principal} nifi.kerberos.service.principal=${nifi.kerberos.service.principal}
nifi.kerberos.keytab.location=${nifi.kerberos.keytab.location} nifi.kerberos.service.keytab.location=${nifi.kerberos.service.keytab.location}
nifi.kerberos.authentication.expiration=${nifi.kerberos.authentication.expiration} 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}

View File

@ -23,8 +23,11 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.FileSystemResource;
import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider; import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider;
import org.springframework.security.kerberos.authentication.KerberosTicketValidator; import org.springframework.security.kerberos.authentication.KerberosTicketValidator;
import org.springframework.security.kerberos.authentication.sun.GlobalSunJaasKerberosConfig;
import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator; import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator;
import java.io.File;
public class KerberosServiceFactoryBean implements FactoryBean<KerberosService> { public class KerberosServiceFactoryBean implements FactoryBean<KerberosService> {
private KerberosService kerberosService = null; private KerberosService kerberosService = null;
@ -32,7 +35,14 @@ public class KerberosServiceFactoryBean implements FactoryBean<KerberosService>
@Override @Override
public KerberosService getObject() throws Exception { 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 = new KerberosService();
kerberosService.setKerberosServiceAuthenticationProvider(createKerberosServiceAuthenticationProvider()); kerberosService.setKerberosServiceAuthenticationProvider(createKerberosServiceAuthenticationProvider());
} }
@ -68,8 +78,8 @@ public class KerberosServiceFactoryBean implements FactoryBean<KerberosService>
private KerberosTicketValidator createTicketValidator() throws Exception { private KerberosTicketValidator createTicketValidator() throws Exception {
SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator(); SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
ticketValidator.setServicePrincipal(properties.getKerberosServicePrincipal()); ticketValidator.setServicePrincipal(properties.getKerberosSpnegoPrincipal());
ticketValidator.setKeyTabLocation(new FileSystemResource(properties.getKerberosKeytabLocation())); ticketValidator.setKeyTabLocation(new FileSystemResource(properties.getKerberosSpnegoKeytabLocation()));
ticketValidator.afterPropertiesSet(); ticketValidator.afterPropertiesSet();
return ticketValidator; return ticketValidator;
} }

View File

@ -33,6 +33,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider; import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider;
import org.springframework.security.kerberos.authentication.sun.GlobalSunJaasKerberosConfig;
import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient; import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient;
import java.util.concurrent.TimeUnit; 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)); 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(); provider = new KerberosAuthenticationProvider();
SunJaasKerberosClient client = new SunJaasKerberosClient(); SunJaasKerberosClient client = new SunJaasKerberosClient();
client.setDebug(true); client.setDebug(true);

View File

@ -102,7 +102,7 @@ public class RangerNiFiAuthorizer implements Authorizer {
// login with the nifi principal and keytab, RangerAdminRESTClient will use Ranger's MiscUtil which // login with the nifi principal and keytab, RangerAdminRESTClient will use Ranger's MiscUtil which
// will grab UserGroupInformation.getLoginUser() and call ugi.checkTGTAndReloginFromKeytab(); // will grab UserGroupInformation.getLoginUser() and call ugi.checkTGTAndReloginFromKeytab();
final String nifiPrincipal = nifiProperties.getKerberosServicePrincipal(); final String nifiPrincipal = nifiProperties.getKerberosServicePrincipal();
final String nifiKeytab = nifiProperties.getKerberosKeytabLocation(); final String nifiKeytab = nifiProperties.getKerberosServiceKeytabLocation();
if (StringUtils.isBlank(nifiPrincipal) || StringUtils.isBlank(nifiKeytab)) { if (StringUtils.isBlank(nifiPrincipal) || StringUtils.isBlank(nifiKeytab)) {
throw new AuthorizerCreationException("Principal and Keytab must be provided when Kerberos is enabled"); throw new AuthorizerCreationException("Principal and Keytab must be provided when Kerberos is enabled");

View File

@ -149,7 +149,7 @@ public class TestRangerNiFiAuthorizer {
.thenReturn(new MockPropertyValue("true")); .thenReturn(new MockPropertyValue("true"));
nifiProperties = Mockito.mock(NiFiProperties.class); nifiProperties = Mockito.mock(NiFiProperties.class);
when(nifiProperties.getKerberosKeytabLocation()).thenReturn(""); when(nifiProperties.getKerberosServiceKeytabLocation()).thenReturn("");
authorizer = new MockRangerNiFiAuthorizer(rangerBasePlugin); authorizer = new MockRangerNiFiAuthorizer(rangerBasePlugin);
authorizer.setNiFiProperties(nifiProperties); authorizer.setNiFiProperties(nifiProperties);
@ -169,7 +169,7 @@ public class TestRangerNiFiAuthorizer {
.thenReturn(new MockPropertyValue("true")); .thenReturn(new MockPropertyValue("true"));
nifiProperties = Mockito.mock(NiFiProperties.class); nifiProperties = Mockito.mock(NiFiProperties.class);
when(nifiProperties.getKerberosKeytabLocation()).thenReturn(""); when(nifiProperties.getKerberosServiceKeytabLocation()).thenReturn("");
when(nifiProperties.getKerberosServicePrincipal()).thenReturn(""); when(nifiProperties.getKerberosServicePrincipal()).thenReturn("");
authorizer = new MockRangerNiFiAuthorizer(rangerBasePlugin); authorizer = new MockRangerNiFiAuthorizer(rangerBasePlugin);
@ -203,7 +203,7 @@ public class TestRangerNiFiAuthorizer {
.thenReturn(new MockPropertyValue("true")); .thenReturn(new MockPropertyValue("true"));
nifiProperties = Mockito.mock(NiFiProperties.class); nifiProperties = Mockito.mock(NiFiProperties.class);
when(nifiProperties.getKerberosKeytabLocation()).thenReturn("test"); when(nifiProperties.getKerberosServiceKeytabLocation()).thenReturn("test");
when(nifiProperties.getKerberosServicePrincipal()).thenReturn("test"); when(nifiProperties.getKerberosServicePrincipal()).thenReturn("test");
authorizer = new MockRangerNiFiAuthorizer(rangerBasePlugin); authorizer = new MockRangerNiFiAuthorizer(rangerBasePlugin);

View File

@ -173,5 +173,8 @@ nifi.zookeeper.root.node=/nifi
# kerberos # # kerberos #
nifi.kerberos.krb5.file= nifi.kerberos.krb5.file=
nifi.kerberos.service.principal= nifi.kerberos.service.principal=
nifi.kerberos.keytab.location= nifi.kerberos.service.keytab.location=
nifi.kerberos.authentication.expiration=12 hours
nifi.kerberos.spnego.principal=
nifi.kerberos.spnego.keytab.location=
nifi.kerberos.spnego.authentication.expiration=12 hours