NIFI-3051 Fixed issue serializing commented or empty login-identity-providers.xml.

Cleaned up commented pom.xml contents. (+4 squashed commits)
Squashed commits:
[725860b] NIFI-3051 Switched CET test logging dependency from logback to log4j as Zookeeper migration has an explicit dependency on log4j as the logging provider and the two libraries were causing classpath collisions. Now the tests run in both Maven and Intellij, the tools all build successfully, and the tools all run (TLS Toolkit, CET, and ZK) without logging provider warnings and print the expected output to the console.
[0e604c7] NIFI-3051 Changed provider element selection in serialize method to be by class (org.apache.nifi.ldap.LdapProvider) rather than identifier in case it has been modified.
Added unit tests.
[300a23d] NIFI-3051 Changed provider element selection to be by class (org.apache.nifi.ldap.LdapProvider) rather than identifier in case it has been modified.
Added unit tests.
[a0cdd40] NIFI-3051 Fixed issue serializing commented or empty login-identity-providers.xml.
Updated and added unit tests. (+1 squashed commit)
Squashed commits:
[b187202] NIFI-3051 - checked in test demonstrating failure to serialize commented ldap-provider section.

This closes #1238.

Signed-off-by: Andy LoPresto <alopresto@apache.org>
This commit is contained in:
Andy LoPresto 2016-11-16 22:38:59 -05:00
parent 7206318ecf
commit 8568d40cd8
No known key found for this signature in database
GPG Key ID: 3C6EF65B2F7DEF69
7 changed files with 325 additions and 161 deletions

View File

@ -52,16 +52,6 @@
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
</dependency>
<!--<dependency>-->
<!--<groupId>org.codehaus.groovy</groupId>-->
<!--<artifactId>groovy-all</artifactId>-->
<!--<scope>compile</scope>-->
<!--</dependency>-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>
@ -103,32 +93,6 @@
</dependency>
</dependencies>
</plugin>
<!--<plugin>-->
<!--<groupId>org.codehaus.groovy</groupId>-->
<!--<artifactId>groovy-eclipse-compiler</artifactId>-->
<!--<version>2.9.2-01</version>-->
<!--<extensions>true</extensions>-->
<!--</plugin>-->
<!--<plugin>-->
<!--<groupId>org.apache.maven.plugins</groupId>-->
<!--<artifactId>maven-shade-plugin</artifactId>-->
<!--<version>2.1</version>-->
<!--<executions>-->
<!--<execution>-->
<!--<phase>package</phase>-->
<!--<goals>-->
<!--<goal>shade</goal>-->
<!--</goals>-->
<!--</execution>-->
<!--</executions>-->
<!--<configuration>-->
<!--<transformers>-->
<!--<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">-->
<!--<mainClass>ConfigEncryptionTool</mainClass>-->
<!--</transformer>-->
<!--</transformers>-->
<!--</configuration>-->
<!--</plugin>-->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>

View File

@ -34,6 +34,7 @@ import org.bouncycastle.crypto.generators.SCrypt
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.xml.sax.SAXException
import javax.crypto.Cipher
import java.nio.charset.StandardCharsets
@ -96,7 +97,8 @@ class ConfigEncryptionTool {
private static
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>/
private static final String LDAP_PROVIDER_CLASS = "org.apache.nifi.ldap.LdapProvider"
static private final String LDAP_PROVIDER_REGEX = /<provider>[\s\S]*?<class>\s*org\.apache\.nifi\.ldap\.LdapProvider[\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) {
@ -373,7 +375,6 @@ class ConfigEncryptionTool {
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) {
@ -391,7 +392,8 @@ class ConfigEncryptionTool {
try {
def doc = new XmlSlurper().parseText(encryptedXml)
def passwords = doc.provider.find { it.identifier == 'ldap-provider' }.property.findAll {
// Find the provider element by class even if it has been renamed
def passwords = doc.provider.find { it.'class' as String == LDAP_PROVIDER_CLASS }.property.findAll {
it.@name =~ "Password" && it.@encryption =~ "aes/gcm/\\d{3}"
}
@ -427,9 +429,10 @@ class ConfigEncryptionTool {
// 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' }
// Find the provider element by class even if it has been renamed
def passwords = doc.provider.find { it.'class' as String == LDAP_PROVIDER_CLASS }
.property.findAll {
// Only operate on un-encrypted passwords
it.@name =~ "Password" && (it.@encryption == "none" || it.@encryption == "") && it.text()
}
@ -687,19 +690,25 @@ 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")
try {
def parsedXml = new XmlSlurper().parseText(xmlContent)
def provider = parsedXml.provider.find { it.'class' as String == LDAP_PROVIDER_CLASS }
if (provider) {
def serializedProvider = new XmlUtil().serialize(provider)
// Remove XML declaration from top
serializedProvider = serializedProvider.replaceFirst(XML_DECLARATION_REGEX, "")
fileContents = fileContents.replaceFirst(LDAP_PROVIDER_REGEX, serializedProvider)
return fileContents.split("\n")
} else {
throw new SAXException("No ldap-provider element found")
}
} catch (SAXException e) {
logger.error("No provider element with class org.apache.nifi.ldap.LdapProvider found in XML content; the file could be empty or the element may be missing or commented out")
return fileContents.split("\n")
}
}
/**

View File

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<configuration scan="true" scanPeriod="30 seconds">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%date %level [%thread] %logger{40} %msg%n</pattern>
</encoder>
</appender>
<!-- valid logging levels: TRACE, DEBUG, INFO, WARN, ERROR -->
<logger name="org.apache.nifi.util.config" level="INFO">
<appender-ref ref="CONSOLE"/>
</logger>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>

View File

@ -16,9 +16,9 @@
*/
package org.apache.nifi.properties
import ch.qos.logback.classic.spi.LoggingEvent
import ch.qos.logback.core.AppenderBase
import org.apache.commons.lang3.SystemUtils
import org.apache.log4j.AppenderSkeleton
import org.apache.log4j.spi.LoggingEvent
import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException
import org.apache.nifi.util.NiFiProperties
import org.apache.nifi.util.console.TextDevice
@ -2050,7 +2050,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
// Assert
def passwordLines = encryptedLines.findAll { it =~ PASSWORD_PROP_REGEX }
assert passwordLines.size() == LIP_PASSWORD_LINE_COUNT
def populatedPasswordLines = passwordLines.findAll { it.contains(">.*<") }
def populatedPasswordLines = passwordLines.findAll { it =~ />.+</ }
assert populatedPasswordLines.every { !it.contains(">thisIsABadPassword<") }
assert populatedPasswordLines.every { it.contains(encryptionScheme) }
populatedPasswordLines.each {
@ -2136,6 +2136,46 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
}
}
@Test
void testShouldEncryptLoginIdentityProvidersWithRenamedProvider() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-renamed.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")}")
assert lines.findAll { it =~ "ldap-provider" }.empty
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 =~ />.+</ }
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 testEncryptLoginIdentityProvidersShouldHandleCommentedElements() {
// Arrange
@ -2165,6 +2205,141 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
assert encryptedLines == lines
}
@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
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()
// Ensure the replacement actually occurred
assert trimmedSerializedLines.findAll { it =~ "encryption=" }.size() == LIP_PASSWORD_LINE_COUNT
}
@Test
void testSerializeLoginIdentityProvidersAndPreserveFormatShouldHandleRenamedProvider() {
// Arrange
String loginIdentityProvidersPath = "src/test/resources/login-identity-providers-populated-renamed.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
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
assert lines.findAll { it =~ "ldap-provider" }.empty
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()
// Ensure the replacement actually occurred
assert trimmedSerializedLines.findAll { it =~ "encryption=" }.size() == LIP_PASSWORD_LINE_COUNT
}
@Test
void testSerializeLoginIdentityProvidersAndPreserveFormatShouldHandleCommentedFile() {
// 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")}")
// If no sensitive properties are found, the original input text is just returned (comments and formatting in tact)
def encryptedLines = tool.encryptLoginIdentityProviders(lines.join("\n")).split("\n")
logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
assert encryptedLines == lines
// Act
def serializedLines = ConfigEncryptionTool.serializeLoginIdentityProvidersAndPreserveFormat(encryptedLines.join("\n"), workingFile)
logger.info("Serialized lines: \n${serializedLines.join("\n")}")
// Assert
assert serializedLines == encryptedLines
assert TestAppender.events.any { it.renderedMessage =~ "No provider element with class org.apache.nifi.ldap.LdapProvider found in XML content; the file could be empty or the element may be missing or commented out" }
}
@Test
void testSerializeLoginIdentityProvidersAndPreserveFormatShouldHandleEmptyFile() {
// Arrange
File tmpDir = setupTmpDir()
File workingFile = new File("target/tmp/tmp-login-identity-providers.xml")
workingFile.delete()
workingFile.createNewFile()
ConfigEncryptionTool tool = new ConfigEncryptionTool()
tool.isVerbose = true
tool.keyHex = KEY_HEX_128
def lines = workingFile.readLines()
logger.info("Read lines: \n${lines.join("\n")}")
// If no sensitive properties are found, the original input text is just returned (comments and formatting in tact)
def encryptedLines = lines
logger.info("Encrypted lines: \n${encryptedLines.join("\n")}")
// Act
def serializedLines = ConfigEncryptionTool.serializeLoginIdentityProvidersAndPreserveFormat(encryptedLines.join("\n"), workingFile)
logger.info("Serialized lines: \n${serializedLines.join("\n")}")
// Assert
assert serializedLines.findAll { it }.isEmpty()
assert TestAppender.events.any { it.renderedMessage =~ "No provider element with class org.apache.nifi.ldap.LdapProvider found in XML content; the file could be empty or the element may be missing or commented out" }
}
@Test
void testShouldPerformFullOperationForLoginIdentityProviders() {
// Arrange
@ -2327,40 +2502,6 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
// 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
@ -2445,7 +2586,7 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
}
// Check that the comments are still there
def trimmedLines = inputLIPFile.readLines().collect {it.trim() }.findAll { it }
def trimmedLines = inputLIPFile.readLines().collect { it.trim() }.findAll { it }
def trimmedSerializedLines = updatedXmlContent.split("\n").collect { it.trim() }.findAll { it }
assert trimmedLines.size() == trimmedSerializedLines.size()
@ -2477,8 +2618,8 @@ class ConfigEncryptionToolTest extends GroovyTestCase {
}
}
public class TestAppender extends AppenderBase<LoggingEvent> {
static List<LoggingEvent> events = new ArrayList<>();
public class TestAppender extends AppenderSkeleton {
static final List<LoggingEvent> events = new ArrayList<>();
@Override
protected void append(LoggingEvent e) {
@ -2492,4 +2633,13 @@ public class TestAppender extends AppenderBase<LoggingEvent> {
events.clear();
}
}
@Override
void close() {
}
@Override
boolean requiresLayout() {
return false
}
}

View File

@ -15,8 +15,12 @@
# limitations under the License.
#
log4j.rootLogger=DEBUG,console
log4j.rootLogger=DEBUG,console,test
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n
log4j.appender.test=org.apache.nifi.properties.TestAppender
log4j.appender.test.layout=org.apache.log4j.PatternLayout
log4j.appender.test.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n

View File

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%-4r [%t] %-5p %c - %m%n</pattern>
</encoder>
</appender>
<appender name="TEST" class="org.apache.nifi.properties.TestAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%-4r [%t] %-5p %c - %m%n</pattern>
</encoder>
</appender>
<logger name="org.apache.nifi.properties" level="DEBUG"/>
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="TEST"/>
</root>
</configuration>

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>definitely-not-dap-lay-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>