NIFI-2654 Enabled encryption coverage for login-identity-providers.xml.

Squashed commits:
[5dd22a9] NIFI-2654 Updated administration guide with login-identity-providers.xml flags.

Exposed master key retrieval code in NiFiPropertiesLoader.
Added logic to decrypt login identity providers XML configuration.
Updated login-identity-providers.xsd to include encryption scheme attribute.
Added unit tests. (+18 squashed commits)
Squashed commits:
[57c815f] NIFI-2654 Resolved issue where empty LIP property elements could not be encrypted.
Added unit test and resource.
[27d7309] NIFI-2654 Wired in serialization logic to write logic for LIP.
Added comprehensive unit test for LIP & NFP in same test.
[b450eb2] NIFI-2654 Finalized logic for preserving comments in LIP parsing.
[5aa6c9c] NIFI-2654 Added logic for maintaining XML formatting (comments and whitespace) for LIP.
Added unit tests (w/o encryption works; w/ does not).
[b53461f] NIFI-2654 Added unit test for full tool invocation migrating a login-identity-providers.xml file and updating file and bootstrap.conf with key.
[2d9686c] NIFI-2654 Updated tool description and various logging statements.
Added unit test for full tool invocation encrypting a login-identity-providers.xml file and updating file and bootstrap.conf with key.
[8c67cb2] NIFI-2654 Added logic to encrypt LIP XML content.
Added unit tests.
[8682d19] NIFI-2654 Added logic to handle "empty" (commented) LIP files.
Added unit tests.
[077230e] NIFI-2654 Fixed logic to decrypt multiline and multiple-per-line XML elements.
Added unit tests and resources.
[d5bb8da] NIFI-2654 Ignored unit test for unreadable conf directory because directory was causing Maven build issues.
Removed test resources.
[7e50506] NIFI-2654 Fixed AESSensitivePropertyProvider bug handling cipher text with whitespace.
Added unit test.
[b69a661] NIFI-2654 Fixed AESSensitivePropertyProviderFactoryTest to reflect absence of key causes errors.
[6f821b9] NIFI-2654 Added standard password to arbitrary encryption test for use in test resources.
[d289ffa] NIFI-2654 Added LIP XML decryption.
Added unit tests.
[a482245] NIFI-2654 Added LIP test resources.
[7204df4] NIFI-2654 Changed logic to only perform properties encryption when file path is provided.
[729e1df] NIFI-2654 Removed population of default file locations for bootstrap.conf, nifi.properties, and login-identity-providers.xml as not all files may be desired.
Added/updated unit tests.
[7dba5ef] NIFI-2654 Started LIP work (arguments & parsing).
Added unit tests.

Signed-off-by: Yolanda M. Davis <ymdavis@apache.org>

This closes #1216
This commit is contained in:
Andy LoPresto 2016-11-07 20:36:59 -08:00 committed by Yolanda M. Davis
parent 8ad3125168
commit 59fea1cb4e
24 changed files with 2418 additions and 91 deletions

View File

@ -987,17 +987,19 @@ The default encryption algorithm utilized is AES/GCM 128/256-bit. 128-bit is use
You can use the following command line options with the `encrypt-config` tool:
* `-b,--bootstrapConf <arg>` The bootstrap.conf file to persist master key
* `-e,--oldKey <arg>` The old raw hexadecimal key to use during key migration
* `-h,--help` Prints this usage message
* `-k,--key <arg>` The raw hexadecimal key to use to encrypt the sensitive properties
* `-m,--migrate` If provided, the sensitive properties will be re-encrypted with a new key
* `-n,--niFiProperties <arg>` The nifi.properties file containing unprotected config values (will be overwritten)
* `-o,--outputNiFiProperties <arg>` The destination nifi.properties file containing protected config values (will not modify input nifi.properties)
* `-p,--password <arg>` The password from which to derive the key to use to encrypt the sensitive properties
* `-r,--useRawKey` If provided, the secure console will prompt for the raw key value in hexadecimal form
* `-v,--verbose` Sets verbose mode (default false)
* `-w,--oldPassword <arg>` The old password from which to derive the key during migration
* `-b,--bootstrapConf <arg>` The bootstrap.conf file to persist master key
* `-e,--oldKey <arg>` The old raw hexadecimal key to use during key migration
* `-h,--help` Prints this usage message
* `-k,--key <arg>` The raw hexadecimal key to use to encrypt the sensitive properties
* `-m,--migrate` If provided, the sensitive properties will be re-encrypted with a new key
* `-n,--niFiProperties <arg>` The nifi.properties file containing unprotected config values (will be overwritten)
* `-o,--outputNiFiProperties <arg>` The destination nifi.properties file containing protected config values (will not modify input nifi.properties)
* `-p,--password <arg>` The password from which to derive the key to use to encrypt the sensitive properties
* `-r,--useRawKey` If provided, the secure console will prompt for the raw key value in hexadecimal form
* `-v,--verbose` Sets verbose mode (default false)
* `-w,--oldPassword <arg>` The old password from which to derive the key during migration
* `-l,--loginIdentityProviders <arg>` The login-identity-providers.xml file containing unprotected config values (will be overwritten)
* `-i,--outputLoginIdentityProviders <arg>` The destination login-identity-providers.xml file containing protected config values (will not modify input login-identity-providers.xml)
As an example of how the tool works, assume that you have installed the tool on a machine supporting 256-bit encryption and with the following existing values in the 'nifi.properties' file:
@ -1058,6 +1060,23 @@ Sensitive configuration values are encrypted by the tool by default, however you
If the 'nifi.properties' file already has valid protected values, those property values are not modified by the tool.
When applied to 'login-identity-providers.xml', the property elements are updated with an `encryption` attribute:
----
<!-- LDAP Provider -->
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN">someuser</property>
<property name="Manager Password" encryption="aes/gcm/128">q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA</property>
<property name="TLS - Keystore"></property>
<property name="TLS - Keystore Password" encryption="aes/gcm/128">Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g</property>
<property name="TLS - Keystore Type"></property>
...
</provider>
----
In order to change the key used to encrypt the sensitive values, indicate *migration mode* using the `-m` or `--migrate` flag, provide the new key or password using the `-k` or `-p` flags as usual, and provide the existing key or password using `-e` or `-w` respectively. This will allow the toolkit to decrypt the existing values and re-encrypt them, and update `bootstrap.conf` with the new key. Only one of the key or password needs to be specified for each phase (old vs. new), and any combination is sufficient:
* old key -> new key

View File

@ -217,6 +217,8 @@ public class AESSensitivePropertyProvider implements SensitivePropertyProvider {
throw new IllegalArgumentException("The cipher text does not contain the delimiter " + DELIMITER + " -- it should be of the form Base64(IV) || Base64(cipherText)");
}
protectedValue = protectedValue.trim();
final String IV_B64 = protectedValue.substring(0, protectedValue.indexOf(DELIMITER));
byte[] iv = Base64.decode(IV_B64);
if (iv.length < IV_LENGTH) {

View File

@ -102,7 +102,13 @@ public class NiFiPropertiesLoader {
}
}
private static String extractKeyFromBootstrapFile() throws IOException {
/**
* Returns the key (if any) used to encrypt sensitive properties, extracted from {@code $NIFI_HOME/conf/bootstrap.conf}.
*
* @return the key in hexadecimal format
* @throws IOException if the file is not readable
*/
public static String extractKeyFromBootstrapFile() throws IOException {
// Guess at location of bootstrap.conf file from nifi.properties file
String defaultNiFiPropertiesPath = getDefaultFilePath();
File propertiesFile = new File(defaultNiFiPropertiesPath);

View File

@ -56,17 +56,18 @@ class AESSensitivePropertyProviderFactoryTest extends GroovyTestCase {
@Ignore("This is resolved in PR 1216")
@Test
public void testShouldGetProviderWithoutKey() throws Exception {
public void testShouldNotGetProviderWithoutKey() throws Exception {
// Arrange
SensitivePropertyProviderFactory factory = new AESSensitivePropertyProviderFactory()
// Act
SensitivePropertyProvider provider = factory.getProvider()
def msg = shouldFail(SensitivePropertyProtectionException) {
SensitivePropertyProvider provider = factory.getProvider()
}
logger.expected(msg)
// Assert
assert provider instanceof AESSensitivePropertyProvider
assert !provider.@key
assert !provider.@cipher
assert msg == "The provider factory cannot generate providers without a key"
}
@Test
@ -90,11 +91,12 @@ class AESSensitivePropertyProviderFactoryTest extends GroovyTestCase {
SensitivePropertyProviderFactory factory = new AESSensitivePropertyProviderFactory("")
// Act
SensitivePropertyProvider provider = factory.getProvider()
def msg = shouldFail(SensitivePropertyProtectionException) {
SensitivePropertyProvider provider = factory.getProvider()
}
logger.expected(msg)
// Assert
assert provider instanceof AESSensitivePropertyProvider
assert !provider.@key
assert !provider.@cipher
assert msg == "The provider factory cannot generate providers without a key"
}
}

View File

@ -238,6 +238,36 @@ class AESSensitivePropertyProviderTest extends GroovyTestCase {
}
}
@Test
public void testShouldUnprotectValueWithWhitespace() throws Exception {
// Arrange
final String PLAINTEXT = "This is a plaintext value"
Map<Integer, Cipher> encryptionCiphers = KEY_SIZES.collectEntries { int keySize ->
byte[] iv = new byte[IV_LENGTH]
secureRandom.nextBytes(iv)
[(keySize): getCipher(true, keySize, iv)]
}
Map<Integer, String> CIPHER_TEXTS = encryptionCiphers.collectEntries { Map.Entry<Integer, Cipher> e ->
String iv = encoder.encodeToString(e.value.getIV())
String cipherText = encoder.encodeToString(e.value.doFinal(PLAINTEXT.getBytes(StandardCharsets.UTF_8)))
[(e.key): "${iv}||${cipherText}"]
}
CIPHER_TEXTS.each { key, ct -> logger.expected("Cipher text for ${key} length key: ${ct}") }
// Act
Map<Integer, String> plaintexts = CIPHER_TEXTS.collectEntries { int keySize, String cipherText ->
SensitivePropertyProvider spp = new AESSensitivePropertyProvider(Hex.decode(getKeyOfSize(keySize)))
logger.info("Initialized ${spp.name} with key size ${keySize}")
[(keySize): spp.unprotect("\t" + cipherText + "\n")]
}
plaintexts.each { ks, pt -> logger.info("Decrypted for ${ks} length key: ${pt}") }
// Assert
assert plaintexts.every { int ks, String pt -> pt == PLAINTEXT }
}
@Test
public void testShouldHandleUnprotectMalformedValue() throws Exception {
// Arrange

View File

@ -22,6 +22,7 @@ import org.junit.After
import org.junit.AfterClass
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@ -349,6 +350,7 @@ class NiFiPropertiesLoaderGroovyTest extends GroovyTestCase {
Files.setPosixFilePermissions(unreadableFile.toPath(), originalPermissions)
}
@Ignore("Unreadable conf directory breaks build")
@Test
public void testShouldNotExtractKeyFromUnreadableConfDir() throws Exception {
// Arrange

View File

@ -1,14 +0,0 @@
# 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.

View File

@ -16,6 +16,22 @@
*/
package org.apache.nifi.web.security.spring;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authentication.AuthenticationResponse;
import org.apache.nifi.authentication.LoginCredentials;
@ -31,6 +47,11 @@ import org.apache.nifi.authentication.generated.Property;
import org.apache.nifi.authentication.generated.Provider;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.nar.NarCloseable;
import org.apache.nifi.properties.AESSensitivePropertyProviderFactory;
import org.apache.nifi.properties.NiFiPropertiesLoader;
import org.apache.nifi.properties.SensitivePropertyProtectionException;
import org.apache.nifi.properties.SensitivePropertyProvider;
import org.apache.nifi.properties.SensitivePropertyProviderFactory;
import org.apache.nifi.util.NiFiProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,22 +59,6 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
@ -64,6 +69,9 @@ public class LoginIdentityProviderFactoryBean implements FactoryBean, Disposable
private static final String JAXB_GENERATED_PATH = "org.apache.nifi.authentication.generated";
private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
private static SensitivePropertyProviderFactory SENSITIVE_PROPERTY_PROVIDER_FACTORY;
private static SensitivePropertyProvider SENSITIVE_PROPERTY_PROVIDER;
/**
* Load the JAXBContext.
*/
@ -185,12 +193,39 @@ public class LoginIdentityProviderFactoryBean implements FactoryBean, Disposable
final Map<String, String> providerProperties = new HashMap<>();
for (final Property property : provider.getProperty()) {
providerProperties.put(property.getName(), property.getValue());
if (!StringUtils.isBlank(property.getEncryption())) {
String decryptedValue = decryptValue(property.getValue(), property.getEncryption());
providerProperties.put(property.getName(), decryptedValue);
} else {
providerProperties.put(property.getName(), property.getValue());
}
}
return new StandardLoginIdentityProviderConfigurationContext(provider.getIdentifier(), providerProperties);
}
private String decryptValue(String cipherText, String encryptionScheme) throws SensitivePropertyProtectionException {
initializeSensitivePropertyProvider(encryptionScheme);
return SENSITIVE_PROPERTY_PROVIDER.unprotect(cipherText);
}
private static void initializeSensitivePropertyProvider(String encryptionScheme) throws SensitivePropertyProtectionException {
if (SENSITIVE_PROPERTY_PROVIDER == null || !SENSITIVE_PROPERTY_PROVIDER.getIdentifierKey().equalsIgnoreCase(encryptionScheme)) {
try {
String keyHex = getMasterKey();
SENSITIVE_PROPERTY_PROVIDER_FACTORY = new AESSensitivePropertyProviderFactory(keyHex);
SENSITIVE_PROPERTY_PROVIDER = SENSITIVE_PROPERTY_PROVIDER_FACTORY.getProvider();
} catch (IOException e) {
logger.error("Error extracting master key from bootstrap.conf for login identity provider decryption", e);
throw new SensitivePropertyProtectionException("Could not read master key from bootstrap.conf");
}
}
}
private static String getMasterKey() throws IOException {
return NiFiPropertiesLoader.extractKeyFromBootstrapFile();
}
private void performMethodInjection(final LoginIdentityProvider instance, final Class loginIdentityProviderClass)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {

View File

@ -27,7 +27,8 @@
<xs:complexType name="Property">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="NonEmptyStringType"></xs:attribute>
<xs:attribute name="name" type="NonEmptyStringType"/>
<xs:attribute name="encryption" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>

View File

@ -0,0 +1,141 @@
/*
* 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.web.security.spring
import org.apache.nifi.authentication.generated.Property
import org.apache.nifi.authentication.generated.Provider
import org.apache.nifi.properties.AESSensitivePropertyProvider
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.After
import org.junit.AfterClass
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import javax.crypto.Cipher
import java.security.Security
@RunWith(JUnit4.class)
class LoginIdentityProviderFactoryBeanTest extends GroovyTestCase {
private static final Logger logger = LoggerFactory.getLogger(LoginIdentityProviderFactoryBeanTest.class)
// These blocks configure the constant values depending on JCE policies of the machine running the tests
private static final String KEY_HEX_128 = "0123456789ABCDEFFEDCBA9876543210"
private static final String KEY_HEX_256 = KEY_HEX_128 * 2
public static final String KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? KEY_HEX_256 : KEY_HEX_128
private static final String CIPHER_TEXT_128 = "6pqdM1urBEPHtj+L||ds0Z7RpqOA2321c/+7iPMfxDrqmH5Qx6UwQG0eIYB//3Ng"
private static final String CIPHER_TEXT_256 = "TepMCD7v3LAMF0KX||ydSRWPRl1/JXgTsZtfzCnDXu7a0lTLysjPL2I06EPUCHzw"
public static final String CIPHER_TEXT = isUnlimitedStrengthCryptoAvailable() ? CIPHER_TEXT_256 : CIPHER_TEXT_128
private static final String ENCRYPTION_SCHEME_128 = "aes/gcm/128"
private static final String ENCRYPTION_SCHEME_256 = "aes/gcm/256"
public static
final String ENCRYPTION_SCHEME = isUnlimitedStrengthCryptoAvailable() ? ENCRYPTION_SCHEME_256 : ENCRYPTION_SCHEME_128
private static final String PASSWORD = "thisIsABadPassword"
@BeforeClass
public static void setUpOnce() throws Exception {
Security.addProvider(new BouncyCastleProvider())
logger.metaClass.methodMissing = { String name, args ->
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
}
}
@AfterClass
public static void tearDownOnce() throws Exception {
}
@Before
public void setUp() throws Exception {
LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER = new AESSensitivePropertyProvider(KEY_HEX)
}
@After
public void tearDown() throws Exception {
LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER = null
LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER_FACTORY = null
}
private static boolean isUnlimitedStrengthCryptoAvailable() {
Cipher.getMaxAllowedKeyLength("AES") > 128
}
private static int getKeyLength(String keyHex = KEY_HEX) {
keyHex?.size() * 4
}
@Ignore("Can't test without overloading static metaClass method")
@Test
void testShouldInitializeSensitivePropertyProvider() {
// Arrange
assert !LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER
assert !LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER_FACTORY
logger.info("Encryption scheme: ${ENCRYPTION_SCHEME}")
// Act
LoginIdentityProviderFactoryBean.initializeSensitivePropertyProvider(ENCRYPTION_SCHEME)
// Assert
assert LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER
assert LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER_FACTORY
assert LoginIdentityProviderFactoryBean.SENSITIVE_PROPERTY_PROVIDER.getIdentifierKey() == ENCRYPTION_SCHEME
}
@Test
void testShouldDecryptValue() {
// Arrange
logger.info("Encryption scheme: ${ENCRYPTION_SCHEME}")
logger.info("Cipher text: ${CIPHER_TEXT}")
// Act
String decrypted = new LoginIdentityProviderFactoryBean().decryptValue(CIPHER_TEXT, ENCRYPTION_SCHEME)
logger.info("Decrypted ${CIPHER_TEXT} -> ${decrypted}")
// Assert
assert decrypted == PASSWORD
}
@Test
void testShouldLoadEncryptedLoginIdentityProviderConfiguration() {
// Arrange
Provider encryptedProvider = new Provider()
encryptedProvider.identifier ="ldap-provider"
encryptedProvider.clazz = "org.apache.nifi.ldap.LdapProvider"
def managerPasswordName = "Manager Password"
Property managerPasswordProperty = new Property(name: managerPasswordName, value: CIPHER_TEXT, encryption: ENCRYPTION_SCHEME)
encryptedProvider.property = [managerPasswordProperty]
logger.info("Manager Password property: ${managerPasswordProperty.dump()}")
def bean = new LoginIdentityProviderFactoryBean()
// Act
def context = bean.loadLoginIdentityProviderConfiguration(encryptedProvider)
logger.info("Loaded context: ${context.dump()}")
// Assert
assert context.getProperty(managerPasswordName) == PASSWORD
}
}

View File

@ -17,6 +17,7 @@
package org.apache.nifi.properties
import groovy.io.GroovyPrintWriter
import groovy.xml.XmlUtil
import org.apache.commons.cli.CommandLine
import org.apache.commons.cli.CommandLineParser
import org.apache.commons.cli.DefaultParser
@ -46,23 +47,30 @@ class ConfigEncryptionTool {
public String niFiPropertiesPath
public String outputNiFiPropertiesPath
public String loginIdentityProvidersPath
public String outputLoginIdentityProvidersPath
private String keyHex
private String migrationKeyHex
private String password
private String migrationPassword
private NiFiProperties niFiProperties
private String loginIdentityProviders
private boolean usingPassword = true
private boolean usingPasswordMigration = true
private boolean migration = false
private boolean isVerbose = false
private boolean handlingNiFiProperties = false
private boolean handlingLoginIdentityProviders = false
private static final String HELP_ARG = "help"
private static final String VERBOSE_ARG = "verbose"
private static final String BOOTSTRAP_CONF_ARG = "bootstrapConf"
private static final String NIFI_PROPERTIES_ARG = "niFiProperties"
private static final String LOGIN_IDENTITY_PROVIDERS_ARG = "loginIdentityProviders"
private static final String OUTPUT_NIFI_PROPERTIES_ARG = "outputNiFiProperties"
private static final String OUTPUT_LOGIN_IDENTITY_PROVIDERS_ARG = "outputLoginIdentityProviders"
private static final String KEY_ARG = "key"
private static final String PASSWORD_ARG = "password"
private static final String KEY_MIGRATION_ARG = "oldKey"
@ -87,7 +95,9 @@ class ConfigEncryptionTool {
private static final String FOOTER = buildFooter()
private static
final String DEFAULT_DESCRIPTION = "This tool reads from a nifi.properties file with plain sensitive configuration values, prompts the user for a master key, and encrypts each value. It will replace the plain value with the protected value in the same file (or write to a new nifi.properties file if specified)."
final String DEFAULT_DESCRIPTION = "This tool reads from a nifi.properties and/or login-identity-providers.xml file with plain sensitive configuration values, prompts the user for a master key, and encrypts each value. It will replace the plain value with the protected value in the same file (or write to a new file if specified)."
static private final String LDAP_PROVIDER_REGEX = /<provider>\s*<identifier>\s*ldap-provider[\s\S]*?<\/provider>/
static private final String XML_DECLARATION_REGEX = /<\?xml version="1.0" encoding="UTF-8"\?>/
private static String buildHeader(String description = DEFAULT_DESCRIPTION) {
"${SEP}${description}${SEP * 2}"
@ -111,8 +121,10 @@ class ConfigEncryptionTool {
options.addOption("h", HELP_ARG, false, "Prints this usage message")
options.addOption("v", VERBOSE_ARG, false, "Sets verbose mode (default false)")
options.addOption("n", NIFI_PROPERTIES_ARG, true, "The nifi.properties file containing unprotected config values (will be overwritten)")
options.addOption("l", LOGIN_IDENTITY_PROVIDERS_ARG, true, "The login-identity-providers.xml file containing unprotected config values (will be overwritten)")
options.addOption("b", BOOTSTRAP_CONF_ARG, true, "The bootstrap.conf file to persist master key")
options.addOption("o", OUTPUT_NIFI_PROPERTIES_ARG, true, "The destination nifi.properties file containing protected config values (will not modify input nifi.properties)")
options.addOption("i", OUTPUT_LOGIN_IDENTITY_PROVIDERS_ARG, true, "The destination login-identity-providers.xml file containing protected config values (will not modify input login-identity-providers.xml)")
options.addOption("k", KEY_ARG, true, "The raw hexadecimal key to use to encrypt the sensitive properties")
options.addOption("e", KEY_MIGRATION_ARG, true, "The old raw hexadecimal key to use during key migration")
options.addOption("p", PASSWORD_ARG, true, "The password from which to derive the key to use to encrypt the sensitive properties")
@ -141,6 +153,7 @@ class ConfigEncryptionTool {
throw new CommandLineParseException(errorMessage, exitCode);
}
// TODO: Refactor component steps into methods
protected CommandLine parse(String[] args) throws CommandLineParseException {
CommandLineParser parser = new DefaultParser()
CommandLine commandLine
@ -152,15 +165,49 @@ class ConfigEncryptionTool {
isVerbose = commandLine.hasOption(VERBOSE_ARG)
bootstrapConfPath = commandLine.getOptionValue(BOOTSTRAP_CONF_ARG, determineDefaultBootstrapConfPath())
niFiPropertiesPath = commandLine.getOptionValue(NIFI_PROPERTIES_ARG, determineDefaultNiFiPropertiesPath())
outputNiFiPropertiesPath = commandLine.getOptionValue(OUTPUT_NIFI_PROPERTIES_ARG, niFiPropertiesPath)
bootstrapConfPath = commandLine.getOptionValue(BOOTSTRAP_CONF_ARG)
if (niFiPropertiesPath == outputNiFiPropertiesPath) {
// TODO: Add confirmation pause and provide -y flag to offer no-interaction mode?
logger.warn("The source nifi.properties and destination nifi.properties are identical [${outputNiFiPropertiesPath}] so the original will be overwritten")
if (commandLine.hasOption(NIFI_PROPERTIES_ARG)) {
if (isVerbose) {
logger.info("Handling encryption of nifi.properties")
}
niFiPropertiesPath = commandLine.getOptionValue(NIFI_PROPERTIES_ARG)
outputNiFiPropertiesPath = commandLine.getOptionValue(OUTPUT_NIFI_PROPERTIES_ARG, niFiPropertiesPath)
handlingNiFiProperties = true
if (niFiPropertiesPath == outputNiFiPropertiesPath) {
// TODO: Add confirmation pause and provide -y flag to offer no-interaction mode?
logger.warn("The source nifi.properties and destination nifi.properties are identical [${outputNiFiPropertiesPath}] so the original will be overwritten")
}
}
if (commandLine.hasOption(LOGIN_IDENTITY_PROVIDERS_ARG)) {
if (isVerbose) {
logger.info("Handling encryption of login-identity-providers.xml")
}
loginIdentityProvidersPath = commandLine.getOptionValue(LOGIN_IDENTITY_PROVIDERS_ARG)
outputLoginIdentityProvidersPath = commandLine.getOptionValue(OUTPUT_LOGIN_IDENTITY_PROVIDERS_ARG, loginIdentityProvidersPath)
handlingLoginIdentityProviders = true
if (loginIdentityProvidersPath == outputLoginIdentityProvidersPath) {
// TODO: Add confirmation pause and provide -y flag to offer no-interaction mode?
logger.warn("The source login-identity-providers.xml and destination login-identity-providers.xml are identical [${outputLoginIdentityProvidersPath}] so the original will be overwritten")
}
}
if (isVerbose) {
logger.info(" bootstrap.conf: \t${bootstrapConfPath}")
logger.info("(src) nifi.properties: \t${niFiPropertiesPath}")
logger.info("(dest) nifi.properties: \t${outputNiFiPropertiesPath}")
logger.info("(src) login-identity-providers.xml: \t${loginIdentityProvidersPath}")
logger.info("(dest) login-identity-providers.xml: \t${outputLoginIdentityProvidersPath}")
}
// TODO: Implement in NIFI-2655
// if (!commandLine.hasOption(NIFI_PROPERTIES_ARG) && !commandLine.hasOption(LOGIN_IDENTITY_PROVIDERS_ARG)) {
// printUsageAndThrow("One of '-n'/'--${NIFI_PROPERTIES_ARG}' or '-l'/'--${LOGIN_IDENTITY_PROVIDERS_ARG}' must be provided", ExitCode.INVALID_ARGS)
// }
if (commandLine.hasOption(MIGRATION_ARG)) {
migration = true
if (isVerbose) {
@ -169,7 +216,7 @@ class ConfigEncryptionTool {
if (commandLine.hasOption(PASSWORD_MIGRATION_ARG)) {
usingPasswordMigration = true
if (commandLine.hasOption(KEY_MIGRATION_ARG)) {
printUsageAndThrow("Only one of ${PASSWORD_MIGRATION_ARG} and ${KEY_MIGRATION_ARG} can be used", ExitCode.INVALID_ARGS)
printUsageAndThrow("Only one of '-w'/'--${PASSWORD_MIGRATION_ARG}' and '-e'/'--${KEY_MIGRATION_ARG}' can be used", ExitCode.INVALID_ARGS)
} else {
migrationPassword = commandLine.getOptionValue(PASSWORD_MIGRATION_ARG)
}
@ -179,14 +226,14 @@ class ConfigEncryptionTool {
}
} else {
if (commandLine.hasOption(PASSWORD_MIGRATION_ARG) || commandLine.hasOption(KEY_MIGRATION_ARG)) {
printUsageAndThrow("${PASSWORD_MIGRATION_ARG} and ${KEY_MIGRATION_ARG} are ignored unless ${MIGRATION_ARG} is enabled", ExitCode.INVALID_ARGS)
printUsageAndThrow("'-w'/'--${PASSWORD_MIGRATION_ARG}' and '-e'/'--${KEY_MIGRATION_ARG}' are ignored unless '-m'/'--${MIGRATION_ARG}' is enabled", ExitCode.INVALID_ARGS)
}
}
if (commandLine.hasOption(PASSWORD_ARG)) {
usingPassword = true
if (commandLine.hasOption(KEY_ARG)) {
printUsageAndThrow("Only one of ${PASSWORD_ARG} and ${KEY_ARG} can be used", ExitCode.INVALID_ARGS)
printUsageAndThrow("Only one of '-p'/'--${PASSWORD_ARG}' and '-k'/'--${KEY_ARG}' can be used", ExitCode.INVALID_ARGS)
} else {
password = commandLine.getOptionValue(PASSWORD_ARG)
}
@ -310,6 +357,111 @@ class ConfigEncryptionTool {
}
}
/**
* Loads the login identity providers configuration from the provided file path.
*
* @param existingKeyHex the key used to encrypt the configs (defaults to the current key)
*
* @return the file content
* @throw IOException if the login-identity-providers.xml file cannot be read
*/
private String loadLoginIdentityProviders(String existingKeyHex = keyHex) throws IOException {
File loginIdentityProvidersFile
if (loginIdentityProvidersPath && (loginIdentityProvidersFile = new File(loginIdentityProvidersPath)).exists()) {
try {
String xmlContent = loginIdentityProvidersFile.text
List<String> lines = loginIdentityProvidersFile.readLines()
logger.info("Loaded LoginIdentityProviders content (${lines.size()} lines)")
String decryptedXmlContent = decryptLoginIdentityProviders(xmlContent, existingKeyHex)
// String decryptedXmlContent = ConfigEncryptionUtility.decryptLoginIdentityProviders(xmlContent)
return decryptedXmlContent
} catch (RuntimeException e) {
if (isVerbose) {
logger.error("Encountered an error", e)
}
throw new IOException("Cannot load LoginIdentityProviders from [${loginIdentityProvidersPath}]", e)
}
} else {
printUsageAndThrow("Cannot load LoginIdentityProviders from [${loginIdentityProvidersPath}]", ExitCode.ERROR_READING_NIFI_PROPERTIES)
}
}
String decryptLoginIdentityProviders(String encryptedXml, String existingKeyHex = keyHex) {
AESSensitivePropertyProvider sensitivePropertyProvider = new AESSensitivePropertyProvider(existingKeyHex)
try {
def doc = new XmlSlurper().parseText(encryptedXml)
def passwords = doc.provider.find { it.identifier == 'ldap-provider' }.property.findAll {
it.@name =~ "Password" && it.@encryption =~ "aes/gcm/\\d{3}"
}
if (passwords.isEmpty()) {
if (isVerbose) {
logger.info("No encrypted password property elements found in login-identity-providers.xml")
}
return encryptedXml
}
passwords.each { password ->
if (isVerbose) {
logger.info("Attempting to decrypt ${password.text()}")
}
String decryptedValue = sensitivePropertyProvider.unprotect(password.text().trim())
password.replaceNode {
property(name: password.@name, encryption: "none", decryptedValue)
}
}
// Does not preserve whitespace formatting or comments
String updatedXml = XmlUtil.serialize(doc)
logger.info("Updated XML content: ${updatedXml}")
updatedXml
} catch (Exception e) {
printUsageAndThrow("Cannot decrypt login identity providers XML content", ExitCode.SERVICE_ERROR)
}
}
String encryptLoginIdentityProviders(String plainXml, String newKeyHex = keyHex) {
AESSensitivePropertyProvider sensitivePropertyProvider = new AESSensitivePropertyProvider(newKeyHex)
// TODO: Switch to XmlParser & XmlNodePrinter to maintain "empty" element structure
try {
def doc = new XmlSlurper().parseText(plainXml)
// Only operate on un-encrypted passwords
def passwords = doc.provider.find { it.identifier == 'ldap-provider' }
.property.findAll {
it.@name =~ "Password" && (it.@encryption == "none" || it.@encryption == "") && it.text()
}
if (passwords.isEmpty()) {
if (isVerbose) {
logger.info("No unencrypted password property elements found in login-identity-providers.xml")
}
return plainXml
}
passwords.each { password ->
if (isVerbose) {
logger.info("Attempting to encrypt ${password.name()}")
}
String encryptedValue = sensitivePropertyProvider.protect(password.text().trim())
password.replaceNode {
property(name: password.@name, encryption: sensitivePropertyProvider.identifierKey, encryptedValue)
}
}
// Does not preserve whitespace formatting or comments
String updatedXml = XmlUtil.serialize(doc)
logger.info("Updated XML content: ${updatedXml}")
updatedXml
} catch (Exception e) {
if (isVerbose) {
logger.error("Encountered exception", e)
}
printUsageAndThrow("Cannot encrypt login identity providers XML content", ExitCode.SERVICE_ERROR)
}
}
/**
* Accepts a {@link NiFiProperties} instance, iterates over all non-empty sensitive properties which are not already marked as protected, encrypts them using the master key, and updates the property with the protected value. Additionally, adds a new sibling property {@code x.y.z.protected=aes/gcm/{128,256}} for each indicating the encryption scheme used.
*
@ -426,6 +578,39 @@ class ConfigEncryptionTool {
lines
}
/**
* Writes the contents of the login identity providers configuration file with encrypted values to the output {@code login-identity-providers.xml} file.
*
* @throw IOException if there is a problem reading or writing the login-identity-providers.xml file
*/
private void writeLoginIdentityProviders() throws IOException {
if (!outputLoginIdentityProvidersPath) {
throw new IllegalArgumentException("Cannot write encrypted properties to empty login-identity-providers.xml path")
}
File outputLoginIdentityProvidersFile = new File(outputLoginIdentityProvidersPath)
if (isSafeToWrite(outputLoginIdentityProvidersFile)) {
try {
String updatedXmlContent
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
if (loginIdentityProvidersFile.exists() && loginIdentityProvidersFile.canRead()) {
// Instead of just writing the XML content to a file, this method attempts to maintain the structure of the original file and preserves comments
updatedXmlContent = serializeLoginIdentityProvidersAndPreserveFormat(loginIdentityProviders, loginIdentityProvidersFile).join("\n")
}
// Write the updated values back to the file
outputLoginIdentityProvidersFile.text = updatedXmlContent
} catch (IOException e) {
def msg = "Encountered an exception updating the login-identity-providers.xml file with the encrypted values"
logger.error(msg, e)
throw e
}
} else {
throw new IOException("The login-identity-providers.xml file at ${outputLoginIdentityProvidersPath} must be writable by the user running this tool")
}
}
/**
* Writes the contents of the {@link NiFiProperties} instance with encrypted values to the output {@code nifi.properties} file.
*
@ -502,6 +687,21 @@ class ConfigEncryptionTool {
out.toString().split("\n")
}
private
static List<String> serializeLoginIdentityProvidersAndPreserveFormat(String xmlContent, File originalLoginIdentityProvidersFile) {
def parsedXml = new XmlSlurper().parseText(xmlContent)
def provider = parsedXml.provider.find { it.identifier == "ldap-provider" }
def serializedProvider = new XmlUtil().serialize(provider)
// Remove XML declaration from top
serializedProvider = serializedProvider.replaceFirst(XML_DECLARATION_REGEX, "")
// Find the provider element of the new XML in the file contents
String fileContents = originalLoginIdentityProvidersFile.text
fileContents = fileContents.replaceFirst(LDAP_PROVIDER_REGEX, serializedProvider)
fileContents.split("\n")
}
/**
* Helper method which returns true if it is "safe" to write to the provided file.
*
@ -527,6 +727,11 @@ class ConfigEncryptionTool {
"${niFiToolkitPath ? niFiToolkitPath + "/" : ""}conf/nifi.properties"
}
private static String determineDefaultLoginIdentityProvidersPath() {
String niFiToolkitPath = System.getenv(NIFI_TOOLKIT_HOME) ?: ""
"${niFiToolkitPath ? niFiToolkitPath + "/" : ""}conf/login-identity-providers.xml"
}
private static String deriveKeyFromPassword(String password) {
password = password?.trim()
if (!password || password.length() < MIN_PASSWORD_LENGTH) {
@ -600,12 +805,23 @@ class ConfigEncryptionTool {
}
String existingKeyHex = tool.migrationKeyHex ?: tool.keyHex
try {
tool.niFiProperties = tool.loadNiFiProperties(existingKeyHex)
} catch (Exception e) {
tool.printUsageAndThrow("Cannot migrate key if no previous encryption occurred", ExitCode.ERROR_READING_NIFI_PROPERTIES)
if (tool.handlingNiFiProperties) {
try {
tool.niFiProperties = tool.loadNiFiProperties(existingKeyHex)
} catch (Exception e) {
tool.printUsageAndThrow("Cannot migrate key if no previous encryption occurred", ExitCode.ERROR_READING_NIFI_PROPERTIES)
}
tool.niFiProperties = tool.encryptSensitiveProperties(tool.niFiProperties)
}
if (tool.handlingLoginIdentityProviders) {
try {
tool.loginIdentityProviders = tool.loadLoginIdentityProviders(existingKeyHex)
} catch (Exception e) {
tool.printUsageAndThrow("Cannot migrate key if no previous encryption occurred", ExitCode.ERROR_INCORRECT_NUMBER_OF_PASSWORDS)
}
tool.loginIdentityProviders = tool.encryptLoginIdentityProviders(tool.loginIdentityProviders)
}
tool.niFiProperties = tool.encryptSensitiveProperties(tool.niFiProperties)
} catch (CommandLineParseException e) {
if (e.exitCode == ExitCode.HELP) {
System.exit(ExitCode.HELP.ordinal())
@ -622,7 +838,12 @@ class ConfigEncryptionTool {
// Do this as part of a transaction?
synchronized (this) {
tool.writeKeyToBootstrapConf()
tool.writeNiFiProperties()
if (tool.handlingNiFiProperties) {
tool.writeNiFiProperties()
}
if (tool.handlingLoginIdentityProviders) {
tool.writeLoginIdentityProviders()
}
}
} catch (Exception e) {
if (tool.isVerbose) {

View File

@ -25,6 +25,7 @@ import org.apache.nifi.util.console.TextDevice
import org.apache.nifi.util.console.TextDevices
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.After
import org.junit.AfterClass
import org.junit.Assume
import org.junit.Before
import org.junit.BeforeClass
@ -60,10 +61,15 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
public static final String KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? KEY_HEX_256 : KEY_HEX_128
private static final String PASSWORD = "thisIsABadPassword"
// From ConfigEncryptionTool.deriveKeyFromPassword("thisIsABadPassword")
private static final String PASSWORD_KEY_HEX_256 = "2C576A9585DB862F5ECBEE5B4FFFCCA14B18D8365968D7081651006507AD2BDE"
private static
final String PASSWORD_KEY_HEX_256 = "2C576A9585DB862F5ECBEE5B4FFFCCA14B18D8365968D7081651006507AD2BDE"
private static final String PASSWORD_KEY_HEX_128 = "2C576A9585DB862F5ECBEE5B4FFFCCA1"
private static final String PASSWORD_KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? PASSWORD_KEY_HEX_256 : PASSWORD_KEY_HEX_128
private static
final String PASSWORD_KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? PASSWORD_KEY_HEX_256 : PASSWORD_KEY_HEX_128
private static final int LIP_PASSWORD_LINE_COUNT = 3
private final String PASSWORD_PROP_REGEX = "<property[^>]* name=\".* Password\""
@BeforeClass
public static void setUpOnce() throws Exception {
@ -72,6 +78,14 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
logger.metaClass.methodMissing = { String name, args ->
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
}
setupTmpDir()
}
@AfterClass
public static void tearDownOnce() throws Exception {
File tmpDir = new File("target/tmp/")
tmpDir.delete()
}
@Before
@ -87,6 +101,10 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
Cipher.getMaxAllowedKeyLength("AES") > 128
}
private static int getKeyLength(String keyHex = KEY_HEX) {
keyHex?.size() * 4
}
private static void printProperties(NiFiProperties properties) {
if (!(properties instanceof ProtectedNiFiProperties)) {
properties = new ProtectedNiFiProperties(properties)
@ -139,6 +157,13 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
formattedDate =~ datePattern
}
private static File setupTmpDir(String tmpDirPath = "target/tmp/") {
File tmpDir = new File(tmpDirPath)
tmpDir.mkdirs()
setFilePermissions(tmpDir, [PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.GROUP_READ, PosixFilePermission.GROUP_WRITE, PosixFilePermission.GROUP_EXECUTE, PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_WRITE, PosixFilePermission.OTHERS_EXECUTE])
tmpDir
}
@Test
void testShouldPrintHelpMessage() {
// Arrange
@ -174,20 +199,6 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
}
}
@Test
void testParseShouldPopulateDefaultBootstrapConfArgument() {
// Arrange
String bootstrapPath = "conf/bootstrap.conf"
ConfigEncryptionTool tool = new ConfigEncryptionTool()
// Act
tool.parse([] as String[])
logger.info("Parsed bootstrap.conf location: ${tool.bootstrapConfPath}")
// Assert
assert new File(tool.bootstrapConfPath).getPath() == new File(bootstrapPath).getPath()
}
@Test
void testShouldParseNiFiPropertiesArgument() {
// Arrange
@ -202,9 +213,12 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
// Assert
assert tool.niFiPropertiesPath == niFiPropertiesPath
assert tool.handlingNiFiProperties
}
}
// TODO: Remove as part of NIFI-2655
@Ignore("Remove as part of NIFI-2655")
@Test
void testParseShouldPopulateDefaultNiFiPropertiesArgument() {
// Arrange
@ -228,7 +242,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
// Act
flags.each { String arg ->
tool.parse([arg, niFiPropertiesPath] as String[])
tool.parse([arg, niFiPropertiesPath, "-n", niFiPropertiesPath] as String[])
logger.info("Parsed output nifi.properties location: ${tool.outputNiFiPropertiesPath}")
// Assert
@ -236,6 +250,8 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
}
}
// TODO: Remove as part of NIFI-2655
@Ignore("Remove as part of NIFI-2655")
@Test
void testParseShouldPopulateDefaultOutputNiFiPropertiesArgument() {
// Arrange
@ -266,6 +282,91 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
assert TestAppender.events.first().message =~ "The source nifi.properties and destination nifi.properties are identical \\[.*\\] so the original will be overwritten"
}
@Test
void testShouldParseLoginIdentityProvidersArgument() {
// Arrange
def flags = ["-l", "--loginIdentityProviders"]
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers.xml"
ConfigEncryptionTool tool = new ConfigEncryptionTool()
// Act
flags.each { String arg ->
tool.parse([arg, loginIdentityProvidersPath] as String[])
logger.info("Parsed login-identity-providers.xml location: ${tool.loginIdentityProvidersPath}")
// Assert
assert tool.loginIdentityProvidersPath == loginIdentityProvidersPath
assert tool.handlingLoginIdentityProviders
}
}
// TODO: Remove as part of NIFI-2655
@Ignore("Remove as part of NIFI-2655")
@Test
void testParseShouldPopulateDefaultLoginIdentityProvidersArgument() {
// Arrange
String loginIdentityProvidersPath = "conf/login-identity-providers.xml"
ConfigEncryptionTool tool = new ConfigEncryptionTool()
// Act
tool.parse([] as String[])
logger.info("Parsed login-identity-providers.xml location: ${tool.loginIdentityProvidersPath}")
// Assert
assert new File(tool.loginIdentityProvidersPath).getPath() == new File(loginIdentityProvidersPath).getPath()
}
@Test
void testShouldParseOutputLoginIdentityProvidersArgument() {
// Arrange
def flags = ["-i", "--outputLoginIdentityProviders"]
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers.xml"
ConfigEncryptionTool tool = new ConfigEncryptionTool()
// Act
flags.each { String arg ->
tool.parse([arg, loginIdentityProvidersPath, "-l", loginIdentityProvidersPath] as String[])
logger.info("Parsed output login-identity-providers.xml location: ${tool.outputLoginIdentityProvidersPath}")
// Assert
assert tool.outputLoginIdentityProvidersPath == loginIdentityProvidersPath
}
}
// TODO: Remove as part of NIFI-2655
@Ignore("Remove as part of NIFI-2655")
@Test
void testParseShouldPopulateDefaultOutputLoginIdentityProvidersArgument() {
// Arrange
String loginIdentityProvidersPath = "conf/login-identity-providers.xml"
ConfigEncryptionTool tool = new ConfigEncryptionTool()
// Act
tool.parse([] as String[])
logger.info("Parsed output login-identity-providers.xml location: ${tool.outputLoginIdentityProvidersPath}")
// Assert
assert new File(tool.outputLoginIdentityProvidersPath).getPath() == new File(loginIdentityProvidersPath).getPath()
}
@Test
void testParseShouldWarnIfLoginIdentityProvidersWillBeOverwritten() {
// Arrange
String loginIdentityProvidersPath = "conf/login-identity-providers.xml"
ConfigEncryptionTool tool = new ConfigEncryptionTool()
// Act
tool.parse("-l ${loginIdentityProvidersPath} -i ${loginIdentityProvidersPath}".split(" ") as String[])
logger.info("Parsed login-identity-providers.xml location: ${tool.loginIdentityProvidersPath}")
logger.info("Parsed output login-identity-providers.xml location: ${tool.outputLoginIdentityProvidersPath}")
// Assert
assert !TestAppender.events.isEmpty()
assert TestAppender.events.any {
it.message =~ "The source login-identity-providers.xml and destination login-identity-providers.xml are identical \\[.*\\] so the original will be overwritten"
}
}
@Test
void testShouldParseKeyArgument() {
// Arrange
@ -294,7 +395,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
logger.expected(msg)
// Assert
assert msg =~ "Only one of oldPassword and oldKey can be used"
assert msg =~ "Only one of '-w'/'--oldPassword' and '-e'/'--oldKey' can be used"
}
@Test
@ -307,13 +408,14 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
// Act
argStrings.each { String argString ->
argString += " -n any/path"
def msg = shouldFail {
tool.parse(argString.split(" ") as String[])
}
logger.expected(msg)
// Assert
assert msg == "oldPassword and oldKey are ignored unless migrate is enabled"
assert msg == "'-w'/'--oldPassword' and '-e'/'--oldKey' are ignored unless '-m'/'--migrate' is enabled"
}
}
@ -597,7 +699,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
@Test
void testShouldHandleKeyAndPasswordFlag() {
// Arrange
def args = ["-k", KEY_HEX, "-p", PASSWORD]
def args = ["-k", KEY_HEX, "-p", PASSWORD, "-n", ""]
logger.info("Using args: ${args}")
// Act
@ -607,7 +709,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
logger.expected(msg)
// Assert
assert msg == "Only one of password and key can be used"
assert msg == "Only one of '-p'/'--password' and '-k'/'--key' can be used"
}
@Test
@ -1652,6 +1754,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
exit.checkAssertionAfterwards(new Assertion() {
public void checkAssertion() {
assert outputPropertiesFile.exists()
final List<String> updatedPropertiesLines = outputPropertiesFile.readLines()
logger.info("Updated nifi.properties:")
logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
@ -1751,6 +1854,627 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
// Assertions in common method above
}
@Test
void testShouldDecryptLoginIdentityProviders() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-encrypted.xml"
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
ConfigEncryptionTool tool = new ConfigEncryptionTool()
// Sanity check for decryption
String cipherText = "q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA"
String EXPECTED_PASSWORD = "thisIsABadPassword"
AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX_128)
assert spp.unprotect(cipherText) == EXPECTED_PASSWORD
tool.keyHex = KEY_HEX_128
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
// Act
def decryptedLines = tool.decryptLoginIdentityProviders(lines.join("\n")).split("\n")
logger.info("Decrypted lines: \n${decryptedLines.join("\n")}")
// Assert
def passwordLines = decryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
assert passwordLines.every { it =~ ">thisIsABadPassword<" }
// Some lines were not encrypted originally so the encryption attribute would not have been updated
assert passwordLines.any { it =~ "encryption=\"none\"" }
}
@Test
void testShouldDecryptLoginIdentityProvidersWithMultilineElements() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-encrypted-multiline.xml"
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
ConfigEncryptionTool tool = new ConfigEncryptionTool()
tool.isVerbose = true
tool.keyHex = KEY_HEX_128
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
// Act
def decryptedLines = tool.decryptLoginIdentityProviders(lines.join("\n")).split("\n")
logger.info("Decrypted lines: \n${decryptedLines.join("\n")}")
// Assert
def passwordLines = decryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
assert passwordLines.every { it =~ ">thisIsABadPassword<" }
// Some lines were not encrypted originally so the encryption attribute would not have been updated
assert passwordLines.any { it =~ "encryption=\"none\"" }
}
@Test
void testShouldDecryptLoginIdentityProvidersWithMultipleElementsPerLine() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-encrypted-multiple-per-line.xml"
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
ConfigEncryptionTool tool = new ConfigEncryptionTool()
tool.isVerbose = true
tool.keyHex = KEY_HEX_128
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
// Act
def decryptedLines = tool.decryptLoginIdentityProviders(lines.join("\n")).split("\n")
logger.info("Decrypted lines: \n${decryptedLines.join("\n")}")
// Assert
def passwordLines = decryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
assert passwordLines.every { it =~ ">thisIsABadPassword<" }
// Some lines were not encrypted originally so the encryption attribute would not have been updated
assert passwordLines.any { it =~ "encryption=\"none\"" }
}
@Test
void testDecryptLoginIdentityProvidersShouldHandleCommentedElements() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-commented.xml"
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
ConfigEncryptionTool tool = new ConfigEncryptionTool()
tool.isVerbose = true
tool.keyHex = KEY_HEX_128
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
// Act
def decryptedLines = tool.decryptLoginIdentityProviders(lines.join("\n")).split("\n")
logger.info("Decrypted lines: \n${decryptedLines.join("\n")}")
// Assert
// If no encrypted properties are found, the original input text is just returned (comments and formatting in tact)
assert decryptedLines == lines
}
@Test
void testShouldEncryptLoginIdentityProviders() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated.xml"
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
ConfigEncryptionTool tool = new ConfigEncryptionTool()
tool.isVerbose = true
tool.keyHex = KEY_HEX
String encryptionScheme = "encryption=\"aes/gcm/${getKeyLength(KEY_HEX)}\""
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
// Act
def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
// Assert
def passwordLines = encryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
assert passwordLines.every { !it.contains(">thisIsABadPassword<") }
assert passwordLines.every { it.contains(encryptionScheme) }
passwordLines.each {
String ct = (it =~ ">(.*)</property>")[0][1]
logger.info("Cipher text: ${ct}")
assert spp.unprotect(ct) == PASSWORD
}
}
@Test
void testShouldEncryptLoginIdentityProvidersWithEmptySensitiveElements() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-empty.xml"
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
ConfigEncryptionTool tool = new ConfigEncryptionTool()
tool.isVerbose = true
tool.keyHex = KEY_HEX
String encryptionScheme = "encryption=\"aes/gcm/${getKeyLength(KEY_HEX)}\""
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
// Act
def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
// Assert
def passwordLines = encryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
def populatedPasswordLines = passwordLines.findAll { it.contains(">.*<") }
assert populatedPasswordLines.every { !it.contains(">thisIsABadPassword<") }
assert populatedPasswordLines.every { it.contains(encryptionScheme) }
populatedPasswordLines.each {
String ct = (it =~ ">(.*)</property>")[0][1]
logger.info("Cipher text: ${ct}")
assert spp.unprotect(ct) == PASSWORD
}
}
@Test
void testShouldEncryptLoginIdentityProvidersWithMultilineElements() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-multiline.xml"
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
ConfigEncryptionTool tool = new ConfigEncryptionTool()
tool.isVerbose = true
tool.keyHex = KEY_HEX
String encryptionScheme = "encryption=\"aes/gcm/${getKeyLength(KEY_HEX)}\""
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
// Act
def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
// Assert
def passwordLines = encryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
assert passwordLines.every { !it.contains(">thisIsABadPassword<") }
assert passwordLines.every { it.contains(encryptionScheme) }
passwordLines.each {
String ct = (it =~ ">(.*)</property>")[0][1]
logger.info("Cipher text: ${ct}")
assert spp.unprotect(ct) == PASSWORD
}
}
@Test
void testShouldEncryptLoginIdentityProvidersWithMultipleElementsPerLine() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-multiple-per-line.xml"
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
ConfigEncryptionTool tool = new ConfigEncryptionTool()
tool.isVerbose = true
tool.keyHex = KEY_HEX
String encryptionScheme = "encryption=\"aes/gcm/${getKeyLength(KEY_HEX)}\""
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
// Act
def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
// Assert
def passwordLines = encryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
assert passwordLines.every { !it.contains(">thisIsABadPassword<") }
assert passwordLines.every { it.contains(encryptionScheme) }
passwordLines.each {
String ct = (it =~ ">(.*)</property>")[0][1]
logger.info("Cipher text: ${ct}")
assert spp.unprotect(ct) == PASSWORD
}
}
@Test
void testEncryptLoginIdentityProvidersShouldHandleCommentedElements() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-commented.xml"
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
ConfigEncryptionTool tool = new ConfigEncryptionTool()
tool.isVerbose = true
tool.keyHex = KEY_HEX_128
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
// Act
def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
// Assert
// If no sensitive properties are found, the original input text is just returned (comments and formatting in tact)
assert encryptedLines == lines
}
@Test
void testShouldPerformFullOperationForLoginIdentityProviders() {
// Arrange
exit.expectSystemExitWithStatus(0)
File tmpDir = setupTmpDir()
File emptyKeyFile = new File("src/test/resources/bootstrap_with_empty_master_key.conf")
File bootstrapFile = new File("target/tmp/tmp_bootstrap.conf")
bootstrapFile.delete()
Files.copy(emptyKeyFile.toPath(), bootstrapFile.toPath())
final List<String> originalBootstrapLines = bootstrapFile.readLines()
String originalKeyLine = originalBootstrapLines.find {
it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
}
logger.info("Original key line from bootstrap.conf: ${originalKeyLine}")
assert originalKeyLine == ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX
final String EXPECTED_KEY_LINE = ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX + KEY_HEX
File inputLIPFile = new File("src/test/resources/login-identity-providers-populated.xml")
File outputLIPFile = new File("target/tmp/tmp-lip.xml")
outputLIPFile.delete()
String originalXmlContent = inputLIPFile.text
logger.info("Original XML content: ${originalXmlContent}")
String[] args = ["-l", inputLIPFile.path, "-b", bootstrapFile.path, "-i", outputLIPFile.path, "-k", KEY_HEX, "-v"]
AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
exit.checkAssertionAfterwards(new Assertion() {
public void checkAssertion() {
final String updatedXmlContent = outputLIPFile.text
logger.info("Updated XML content: ${updatedXmlContent}")
// Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
def originalParsedXml = new XmlSlurper().parseText(originalXmlContent)
def updatedParsedXml = new XmlSlurper().parseText(updatedXmlContent)
assert originalParsedXml != updatedParsedXml
assert originalParsedXml.'**'.findAll { it.@encryption } != updatedParsedXml.'**'.findAll {
it.@encryption
}
def encryptedValues = updatedParsedXml.provider.find {
it.identifier == 'ldap-provider'
}.property.findAll {
it.@name =~ "Password" && it.@encryption =~ "aes/gcm/\\d{3}"
}
encryptedValues.each {
assert spp.unprotect(it.text()) == PASSWORD
}
// Check that the key was persisted to the bootstrap.conf
final List<String> updatedBootstrapLines = bootstrapFile.readLines()
String updatedKeyLine = updatedBootstrapLines.find {
it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
}
logger.info("Updated key line: ${updatedKeyLine}")
assert updatedKeyLine == EXPECTED_KEY_LINE
assert originalBootstrapLines.size() == updatedBootstrapLines.size()
// Clean up
outputLIPFile.deleteOnExit()
bootstrapFile.deleteOnExit()
tmpDir.deleteOnExit()
}
});
// Act
ConfigEncryptionTool.main(args)
logger.info("Invoked #main with ${args.join(" ")}")
// Assert
// Assertions defined above
}
@Test
void testShouldPerformFullOperationMigratingLoginIdentityProviders() {
// Arrange
exit.expectSystemExitWithStatus(0)
File tmpDir = setupTmpDir()
// Start with 128-bit encryption and go to whatever is supported on this system
File emptyKeyFile = new File("src/test/resources/bootstrap_with_master_key_128.conf")
File bootstrapFile = new File("target/tmp/tmp_bootstrap.conf")
bootstrapFile.delete()
Files.copy(emptyKeyFile.toPath(), bootstrapFile.toPath())
final List<String> originalBootstrapLines = bootstrapFile.readLines()
String originalKeyLine = originalBootstrapLines.find {
it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
}
logger.info("Original key line from bootstrap.conf: ${originalKeyLine}")
assert originalKeyLine == ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX + KEY_HEX_128
final String EXPECTED_KEY_LINE = ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX + PASSWORD_KEY_HEX
File inputLIPFile = new File("src/test/resources/login-identity-providers-populated-encrypted.xml")
File outputLIPFile = new File("target/tmp/tmp-lip.xml")
outputLIPFile.delete()
String originalXmlContent = inputLIPFile.text
logger.info("Original XML content: ${originalXmlContent}")
// Migrate from KEY_HEX_128 to PASSWORD_KEY_HEX
String[] args = ["-l", inputLIPFile.path, "-b", bootstrapFile.path, "-i", outputLIPFile.path, "-m", "-e", KEY_HEX_128, "-k", PASSWORD_KEY_HEX, "-v"]
AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(PASSWORD_KEY_HEX)
exit.checkAssertionAfterwards(new Assertion() {
public void checkAssertion() {
final String updatedXmlContent = outputLIPFile.text
logger.info("Updated XML content: ${updatedXmlContent}")
// Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
def originalParsedXml = new XmlSlurper().parseText(originalXmlContent)
def updatedParsedXml = new XmlSlurper().parseText(updatedXmlContent)
assert originalParsedXml != updatedParsedXml
// assert originalParsedXml.'**'.findAll { it.@encryption } != updatedParsedXml.'**'.findAll { it.@encryption }
def encryptedValues = updatedParsedXml.provider.find {
it.identifier == 'ldap-provider'
}.property.findAll {
it.@name =~ "Password" && it.@encryption =~ "aes/gcm/\\d{3}"
}
encryptedValues.each {
assert spp.unprotect(it.text()) == PASSWORD
}
// Check that the key was persisted to the bootstrap.conf
final List<String> updatedBootstrapLines = bootstrapFile.readLines()
String updatedKeyLine = updatedBootstrapLines.find {
it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
}
logger.info("Updated key line: ${updatedKeyLine}")
assert updatedKeyLine == EXPECTED_KEY_LINE
assert originalBootstrapLines.size() == updatedBootstrapLines.size()
// Clean up
outputLIPFile.deleteOnExit()
bootstrapFile.deleteOnExit()
tmpDir.deleteOnExit()
}
});
// Act
ConfigEncryptionTool.main(args)
logger.info("Invoked #main with ${args.join(" ")}")
// Assert
// Assertions defined above
}
@Test
void testSerializeLoginIdentityProvidersAndPreserveFormatShouldRespectComments() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated.xml"
File loginIdentityProvidersFile = new File(loginIdentityProvidersPath)
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
Files.copy(loginIdentityProvidersFile.toPath(), workingFile.toPath())
ConfigEncryptionTool tool = new ConfigEncryptionTool()
tool.isVerbose = true
// Just need to read the lines from the original file, parse them to XML, serialize back, and compare output, as no transformation operation will occur
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
String plainXml = workingFile.text
String encryptedXml = tool.encryptLoginIdentityProviders(plainXml, KEY_HEX)
logger.info("Encrypted XML: \n${encryptedXml}")
// Act
def serializedLines = tool.serializeLoginIdentityProvidersAndPreserveFormat(encryptedXml, workingFile)
logger.info("Serialized lines: \n${serializedLines.join("\n")}")
// Assert
// Some empty lines will be removed
def trimmedLines = lines.collect {it.trim() }.findAll { it }
def trimmedSerializedLines = serializedLines.collect { it.trim() }.findAll { it }
assert trimmedLines.size() == trimmedSerializedLines.size()
}
@Test
void testShouldPerformFullOperationForNiFiPropertiesAndLoginIdentityProviders() {
// Arrange
exit.expectSystemExitWithStatus(0)
File tmpDir = setupTmpDir()
File emptyKeyFile = new File("src/test/resources/bootstrap_with_empty_master_key.conf")
File bootstrapFile = new File("target/tmp/tmp_bootstrap.conf")
bootstrapFile.delete()
Files.copy(emptyKeyFile.toPath(), bootstrapFile.toPath())
final List<String> originalBootstrapLines = bootstrapFile.readLines()
String originalKeyLine = originalBootstrapLines.find {
it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
}
logger.info("Original key line from bootstrap.conf: ${originalKeyLine}")
assert originalKeyLine == ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX
final String EXPECTED_KEY_LINE = ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX + KEY_HEX
// Set up the NFP file
File inputPropertiesFile = new File("src/test/resources/nifi_with_sensitive_properties_unprotected.properties")
File outputPropertiesFile = new File("target/tmp/tmp_nifi.properties")
outputPropertiesFile.delete()
NiFiProperties inputProperties = new NiFiPropertiesLoader().load(inputPropertiesFile)
logger.info("Loaded ${inputProperties.size()} properties from input file")
ProtectedNiFiProperties protectedInputProperties = new ProtectedNiFiProperties(inputProperties)
def originalSensitiveValues = protectedInputProperties.getSensitivePropertyKeys().collectEntries { String key -> [(key): protectedInputProperties.getProperty(key)] }
logger.info("Original sensitive values: ${originalSensitiveValues}")
// Set up the LIP file
File inputLIPFile = new File("src/test/resources/login-identity-providers-populated.xml")
File outputLIPFile = new File("target/tmp/tmp-lip.xml")
outputLIPFile.delete()
String originalXmlContent = inputLIPFile.text
logger.info("Original XML content: ${originalXmlContent}")
String[] args = ["-n", inputPropertiesFile.path, "-l", inputLIPFile.path, "-b", bootstrapFile.path, "-i", outputLIPFile.path, "-o", outputPropertiesFile.path, "-k", KEY_HEX, "-v"]
AESSensitivePropertyProvider spp = new AESSensitivePropertyProvider(KEY_HEX)
exit.checkAssertionAfterwards(new Assertion() {
public void checkAssertion() {
final List<String> updatedPropertiesLines = outputPropertiesFile.readLines()
logger.info("Updated nifi.properties:")
logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
// Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(outputPropertiesFile)
assert updatedProperties.size() >= inputProperties.size()
originalSensitiveValues.every { String key, String originalValue ->
assert updatedProperties.getProperty(key) != originalValue
}
// Check that the new NiFiProperties instance matches the output file (values still encrypted)
updatedProperties.getPropertyKeys().every { String key ->
assert updatedPropertiesLines.contains("${key}=${updatedProperties.getProperty(key)}".toString())
}
final String updatedXmlContent = outputLIPFile.text
logger.info("Updated XML content: ${updatedXmlContent}")
// Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
def originalParsedXml = new XmlSlurper().parseText(originalXmlContent)
def updatedParsedXml = new XmlSlurper().parseText(updatedXmlContent)
assert originalParsedXml != updatedParsedXml
assert originalParsedXml.'**'.findAll { it.@encryption } != updatedParsedXml.'**'.findAll {
it.@encryption
}
def encryptedValues = updatedParsedXml.provider.find {
it.identifier == 'ldap-provider'
}.property.findAll {
it.@name =~ "Password" && it.@encryption =~ "aes/gcm/\\d{3}"
}
encryptedValues.each {
assert spp.unprotect(it.text()) == PASSWORD
}
// Check that the comments are still there
def trimmedLines = inputLIPFile.readLines().collect {it.trim() }.findAll { it }
def trimmedSerializedLines = updatedXmlContent.split("\n").collect { it.trim() }.findAll { it }
assert trimmedLines.size() == trimmedSerializedLines.size()
// Check that the key was persisted to the bootstrap.conf
final List<String> updatedBootstrapLines = bootstrapFile.readLines()
String updatedKeyLine = updatedBootstrapLines.find {
it.startsWith(ConfigEncryptionTool.BOOTSTRAP_KEY_PREFIX)
}
logger.info("Updated key line: ${updatedKeyLine}")
assert updatedKeyLine == EXPECTED_KEY_LINE
assert originalBootstrapLines.size() == updatedBootstrapLines.size()
// Clean up
outputPropertiesFile.deleteOnExit()
outputLIPFile.deleteOnExit()
bootstrapFile.deleteOnExit()
tmpDir.deleteOnExit()
}
});
// Act
ConfigEncryptionTool.main(args)
logger.info("Invoked #main with ${args.join(" ")}")
// Assert
// Assertions defined above
}
}
public class TestAppender extends AppenderBase<LoggingEvent> {

View File

@ -52,7 +52,7 @@ java.arg.13=-XX:+UseG1GC
java.arg.14=-Djava.awt.headless=true
# Master key in hexadecimal format for encrypted sensitive configuration values
nifi.bootstrap.sensitive.key=0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210
nifi.bootstrap.sensitive.key=0123456789ABCDEFFEDCBA9876543210
###
# Notification Services for notifying interested parties when NiFi is stopped, started, dies

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<!-- To enable the ldap-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN"></property>
<property name="Manager Password">thisIsABadPassword</property>
<property name="TLS - Keystore"></property>
<property name="TLS - Keystore Password">thisIsABadPassword</property>
<property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name="TLS - Truststore Password">thisIsABadPassword</property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the ldap-provider remove 2 lines. This is 2 of 2. -->
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<!-- To enable the ldap-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN"></property>
<property name="Manager Password"></property>
<property name="TLS - Keystore"></property>
<property name="TLS - Keystore Password"></property>
<property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name="TLS - Truststore Password"></property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the ldap-provider remove 2 lines. This is 2 of 2. -->
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN">someuser</property>
<property name="Manager Password">thisIsABadPassword</property>
<property name="TLS - Keystore"></property>
<property name="TLS - Keystore Password"></property>
<property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name="TLS - Truststore Password"></property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN">someuser</property>
<property name="Manager Password" encryption=
"aes/gcm/128">q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA</property>
<property name="TLS - Keystore"></property>
<property
name="TLS - Keystore Password"
encryption="aes/gcm/128">
Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g
</property>
<property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name="TLS - Truststore Password">thisIsABadPassword</property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN">someuser</property>
<property name="Manager Password" encryption="aes/gcm/128">q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA</property><property name="TLS - Keystore"></property><property name="TLS - Keystore Password" encryption="aes/gcm/128">Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g</property><property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name="TLS - Truststore Password">thisIsABadPassword</property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN">someuser</property>
<property name="Manager Password" encryption="aes/gcm/128">q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA</property>
<property name="TLS - Keystore"></property>
<property name="TLS - Keystore Password" encryption="aes/gcm/128">Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g</property>
<property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name="TLS - Truststore Password">thisIsABadPassword</property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN"></property>
<property name="Manager Password">
thisIsABadPassword
</property>
<property name="TLS - Keystore"></property>
<property
name="TLS - Keystore Password">thisIsABadPassword
</property>
<property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name=
"TLS - Truststore Password">
thisIsABadPassword</property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN">someuser</property>
<property name="Manager Password" encryption="none">thisIsABadPassword</property><property name="TLS - Keystore"></property><property name="TLS - Keystore Password" encryption="">thisIsABadPassword</property><property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name="TLS - Truststore Password">thisIsABadPassword</property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN"></property><property name="Manager Password">thisIsABadPassword</property>
<property name="TLS - Keystore"></property>
<property name="TLS - Keystore Password">thisIsABadPassword</property><property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property><property name="TLS - Truststore Password">thisIsABadPassword</property><property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN">someuser</property>
<property name="Manager Password">thisIsABadPassword</property>
<property name="TLS - Keystore"></property>
<property name="TLS - Keystore Password">thisIsABadPassword</property>
<property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name="TLS - Truststore Password">thisIsABadPassword</property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This file lists the login identity providers to use when running securely. In order
to use a specific provider it must be configured here and it's identifier
must be specified in the nifi.properties file.
-->
<loginIdentityProviders>
<!--
Identity Provider for users logging in with username/password against an LDAP server.
'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
values are ANONYMOUS, SIMPLE, or START_TLS.
'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
'Manager Password' - The password of the manager that is used to bind to the LDAP server to
search for users.
'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
using START_TLS.
'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
LDAP using START_TLS.
'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
START_TLS (i.e. JKS or PKCS12).
'TLS - Client Auth' - Client authentication policy when connecting to LDAP using START_TLS.
Possible values are REQUIRED, WANT, NONE.
'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
TLSv1.1, TLSv1.2, etc).
'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
before the target context is closed. Defaults to false.
'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
'Url' - Url of the LDAP servier (i.e. ldap://<hostname>:<port>).
'User Search Base' - Base DN for searching for users (i.e. CN=Users,DC=example,DC=com).
'User Search Filter' - Filter for searching for users against the 'User Search Base'.
(i.e. sAMAccountName={0}). The user specified name is inserted into '{0}'.
'Authentication Expiration' - The duration of how long the user authentication is valid
for. If the user never logs out, they will be required to log back in following
this duration.
-->
<provider>
<identifier>ldap-provider</identifier>
<class>org.apache.nifi.ldap.LdapProvider</class>
<property name="Authentication Strategy">START_TLS</property>
<property name="Manager DN"></property>
<property name="Manager Password"></property>
<property name="TLS - Keystore"></property>
<property name="TLS - Keystore Password"></property>
<property name="TLS - Keystore Type"></property>
<property name="TLS - Truststore"></property>
<property name="TLS - Truststore Password"></property>
<property name="TLS - Truststore Type"></property>
<property name="TLS - Client Auth"></property>
<property name="TLS - Protocol"></property>
<property name="TLS - Shutdown Gracefully"></property>
<property name="Referral Strategy">FOLLOW</property>
<property name="Connect Timeout">10 secs</property>
<property name="Read Timeout">10 secs</property>
<property name="Url"></property>
<property name="User Search Base"></property>
<property name="User Search Filter"></property>
<property name="Authentication Expiration">12 hours</property>
</provider>
<!--
Identity Provider for users logging in with username/password against a Kerberos KDC server.
'Default Realm' - Default realm to provide when user enters incomplete user principal (i.e. NIFI.APACHE.ORG).
'Authentication Expiration' - The duration of how long the user authentication is valid for. If the user never logs out, they will be required to log back in following this duration.
-->
<!-- To enable the kerberos-provider remove 2 lines. This is 1 of 2.
<provider>
<identifier>kerberos-provider</identifier>
<class>org.apache.nifi.kerberos.KerberosProvider</class>
<property name="Default Realm">NIFI.APACHE.ORG</property>
<property name="Authentication Expiration">12 hours</property>
</provider>
To enable the kerberos-provider remove 2 lines. This is 2 of 2. -->
</loginIdentityProviders>