mirror of https://github.com/apache/nifi.git
NIFI-14025 Corrected LDAP Provider Trust Store Configuration
- Fixed LDAP Provider support for configuring a Trust Store without a Key Store Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com> This closes #9544.
This commit is contained in:
parent
e327dcdd21
commit
a3f4f7b964
|
@ -91,6 +91,12 @@
|
||||||
<version>7.0.1</version>
|
<version>7.0.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.nifi</groupId>
|
||||||
|
<artifactId>nifi-security-cert-builder</artifactId>
|
||||||
|
<version>2.1.0-SNAPSHOT</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<name>nifi-ldap-iaa-providers</name>
|
<name>nifi-ldap-iaa-providers</name>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -16,12 +16,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.ldap;
|
package org.apache.nifi.ldap;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -38,8 +32,8 @@ import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException
|
||||||
import org.apache.nifi.authentication.exception.ProviderCreationException;
|
import org.apache.nifi.authentication.exception.ProviderCreationException;
|
||||||
import org.apache.nifi.authentication.exception.ProviderDestructionException;
|
import org.apache.nifi.authentication.exception.ProviderDestructionException;
|
||||||
import org.apache.nifi.configuration.NonComponentConfigurationContext;
|
import org.apache.nifi.configuration.NonComponentConfigurationContext;
|
||||||
import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
|
import org.apache.nifi.ldap.ssl.LdapSslContextProvider;
|
||||||
import org.apache.nifi.security.ssl.StandardSslContextBuilder;
|
import org.apache.nifi.ldap.ssl.StandardLdapSslContextProvider;
|
||||||
import org.apache.nifi.util.FormatUtils;
|
import org.apache.nifi.util.FormatUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -249,92 +243,9 @@ public class LdapProvider implements LoginIdentityProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SSLContext getConfiguredSslContext(final NonComponentConfigurationContext configurationContext) {
|
private static SSLContext getConfiguredSslContext(final NonComponentConfigurationContext configurationContext) {
|
||||||
final String rawProtocol = configurationContext.getProperty(ProviderProperty.TLS_PROTOCOL.getProperty());
|
final LdapSslContextProvider ldapSslContextProvider = new StandardLdapSslContextProvider();
|
||||||
|
final Map<String, String> contextProperties = configurationContext.getProperties();
|
||||||
SSLContext sslContext = null;
|
return ldapSslContextProvider.createContext(contextProperties);
|
||||||
try {
|
|
||||||
final KeyStore trustStore = getTrustStore(configurationContext);
|
|
||||||
if (trustStore == null) {
|
|
||||||
logger.debug("Truststore not configured");
|
|
||||||
} else {
|
|
||||||
final StandardSslContextBuilder sslContextBuilder = new StandardSslContextBuilder();
|
|
||||||
sslContextBuilder.protocol(rawProtocol);
|
|
||||||
sslContextBuilder.trustStore(trustStore);
|
|
||||||
|
|
||||||
final KeyStore keyStore = getKeyStore(configurationContext);
|
|
||||||
if (keyStore == null) {
|
|
||||||
logger.debug("Keystore not configured");
|
|
||||||
} else {
|
|
||||||
final String keyStorePassword = configurationContext.getProperty(ProviderProperty.KEYSTORE_PASSWORD.getProperty());
|
|
||||||
final char[] keyPassword = keyStorePassword.toCharArray();
|
|
||||||
|
|
||||||
sslContextBuilder.keyStore(keyStore);
|
|
||||||
sslContextBuilder.keyPassword(keyPassword);
|
|
||||||
sslContext = sslContextBuilder.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
|
||||||
logger.error("Encountered an error configuring TLS for LDAP identity provider: {}", e.getLocalizedMessage());
|
|
||||||
throw new ProviderCreationException("Error configuring TLS for LDAP identity provider", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sslContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static KeyStore getKeyStore(final NonComponentConfigurationContext configurationContext) throws IOException {
|
|
||||||
final String rawKeystore = configurationContext.getProperty(ProviderProperty.KEYSTORE.getProperty());
|
|
||||||
final String rawKeystorePassword = configurationContext.getProperty(ProviderProperty.KEYSTORE_PASSWORD.getProperty());
|
|
||||||
final String rawKeystoreType = configurationContext.getProperty(ProviderProperty.KEYSTORE_TYPE.getProperty());
|
|
||||||
|
|
||||||
final KeyStore keyStore;
|
|
||||||
|
|
||||||
if (rawKeystore == null || rawKeystore.isBlank()) {
|
|
||||||
keyStore = null;
|
|
||||||
} else if (rawKeystorePassword == null) {
|
|
||||||
throw new ProviderCreationException("Keystore Password not configured");
|
|
||||||
} else {
|
|
||||||
final StandardKeyStoreBuilder builder = new StandardKeyStoreBuilder();
|
|
||||||
builder.type(rawKeystoreType);
|
|
||||||
|
|
||||||
final char[] keyStorePassword = rawKeystorePassword.toCharArray();
|
|
||||||
builder.password(keyStorePassword);
|
|
||||||
|
|
||||||
final Path trustStorePath = Paths.get(rawKeystore);
|
|
||||||
try (InputStream trustStoreStream = Files.newInputStream(trustStorePath)) {
|
|
||||||
builder.inputStream(trustStoreStream);
|
|
||||||
keyStore = builder.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return keyStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static KeyStore getTrustStore(final NonComponentConfigurationContext configurationContext) throws IOException {
|
|
||||||
final String rawTruststore = configurationContext.getProperty(ProviderProperty.TRUSTSTORE.getProperty());
|
|
||||||
final String rawTruststorePassword = configurationContext.getProperty(ProviderProperty.TRUSTSTORE_PASSWORD.getProperty());
|
|
||||||
final String rawTruststoreType = configurationContext.getProperty(ProviderProperty.TRUSTSTORE_TYPE.getProperty());
|
|
||||||
|
|
||||||
final KeyStore trustStore;
|
|
||||||
|
|
||||||
if (rawTruststore == null || rawTruststore.isBlank()) {
|
|
||||||
trustStore = null;
|
|
||||||
} else if (rawTruststorePassword == null) {
|
|
||||||
throw new ProviderCreationException("Truststore Password not configured");
|
|
||||||
} else {
|
|
||||||
final StandardKeyStoreBuilder builder = new StandardKeyStoreBuilder();
|
|
||||||
builder.type(rawTruststoreType);
|
|
||||||
|
|
||||||
final char[] trustStorePassword = rawTruststorePassword.toCharArray();
|
|
||||||
builder.password(trustStorePassword);
|
|
||||||
|
|
||||||
final Path trustStorePath = Paths.get(rawTruststore);
|
|
||||||
try (InputStream trustStoreStream = Files.newInputStream(trustStorePath)) {
|
|
||||||
builder.inputStream(trustStoreStream);
|
|
||||||
trustStore = builder.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return trustStore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.ldap.ssl;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction for creating an SSLContext from LDAP configuration properties
|
||||||
|
*/
|
||||||
|
public interface LdapSslContextProvider {
|
||||||
|
/**
|
||||||
|
* Create SSLContext from configuration properties
|
||||||
|
*
|
||||||
|
* @param properties Provider properties
|
||||||
|
* @return SSLContext
|
||||||
|
*/
|
||||||
|
SSLContext createContext(Map<String, String> properties);
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* 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.ldap.ssl;
|
||||||
|
|
||||||
|
import org.apache.nifi.authentication.exception.ProviderCreationException;
|
||||||
|
import org.apache.nifi.ldap.ProviderProperty;
|
||||||
|
import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
|
||||||
|
import org.apache.nifi.security.ssl.StandardSslContextBuilder;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard implementation of LDAP SSLContext Provider supporting common properties
|
||||||
|
*/
|
||||||
|
public class StandardLdapSslContextProvider implements LdapSslContextProvider {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(StandardLdapSslContextProvider.class);
|
||||||
|
|
||||||
|
private static final String DEFAULT_PROTOCOL = "TLS";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create SSLContext using configured properties defaulting to system trust store when trust store properties not configured
|
||||||
|
*
|
||||||
|
* @param properties Provider properties
|
||||||
|
* @return SSLContext initialized using configured properties
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SSLContext createContext(final Map<String, String> properties) {
|
||||||
|
Objects.requireNonNull(properties, "Properties required");
|
||||||
|
|
||||||
|
final String rawProtocol = properties.get(ProviderProperty.TLS_PROTOCOL.getProperty());
|
||||||
|
final String protocol;
|
||||||
|
if (rawProtocol == null || rawProtocol.isBlank()) {
|
||||||
|
protocol = DEFAULT_PROTOCOL;
|
||||||
|
} else {
|
||||||
|
protocol = rawProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final SSLContext sslContext;
|
||||||
|
final StandardSslContextBuilder sslContextBuilder = new StandardSslContextBuilder();
|
||||||
|
sslContextBuilder.protocol(protocol);
|
||||||
|
|
||||||
|
final KeyStore trustStore = getTrustStore(properties);
|
||||||
|
if (trustStore == null) {
|
||||||
|
logger.debug("LDAP TLS Truststore not configured");
|
||||||
|
} else {
|
||||||
|
sslContextBuilder.trustStore(trustStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
final KeyStore keyStore = getKeyStore(properties);
|
||||||
|
if (keyStore == null) {
|
||||||
|
logger.debug("LDAP TLS Keystore not configured");
|
||||||
|
} else {
|
||||||
|
final String keyStorePassword = properties.get(ProviderProperty.KEYSTORE_PASSWORD.getProperty());
|
||||||
|
final char[] keyPassword = keyStorePassword.toCharArray();
|
||||||
|
|
||||||
|
sslContextBuilder.keyStore(keyStore);
|
||||||
|
sslContextBuilder.keyPassword(keyPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
sslContext = sslContextBuilder.build();
|
||||||
|
return sslContext;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new ProviderCreationException("Error configuring TLS for LDAP Provider", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyStore getKeyStore(final Map<String, String> properties) throws IOException {
|
||||||
|
final String rawKeystore = properties.get(ProviderProperty.KEYSTORE.getProperty());
|
||||||
|
final String rawKeystorePassword = properties.get(ProviderProperty.KEYSTORE_PASSWORD.getProperty());
|
||||||
|
final String rawKeystoreType = properties.get(ProviderProperty.KEYSTORE_TYPE.getProperty());
|
||||||
|
|
||||||
|
final KeyStore keyStore;
|
||||||
|
|
||||||
|
if (rawKeystore == null || rawKeystore.isBlank()) {
|
||||||
|
keyStore = null;
|
||||||
|
} else if (rawKeystorePassword == null) {
|
||||||
|
throw new ProviderCreationException("Keystore Password not configured");
|
||||||
|
} else {
|
||||||
|
final StandardKeyStoreBuilder builder = new StandardKeyStoreBuilder();
|
||||||
|
builder.type(rawKeystoreType);
|
||||||
|
|
||||||
|
final char[] keyStorePassword = rawKeystorePassword.toCharArray();
|
||||||
|
builder.password(keyStorePassword);
|
||||||
|
|
||||||
|
final Path trustStorePath = Paths.get(rawKeystore);
|
||||||
|
try (InputStream trustStoreStream = Files.newInputStream(trustStorePath)) {
|
||||||
|
builder.inputStream(trustStoreStream);
|
||||||
|
keyStore = builder.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyStore getTrustStore(final Map<String, String> properties) throws IOException {
|
||||||
|
final String rawTruststore = properties.get(ProviderProperty.TRUSTSTORE.getProperty());
|
||||||
|
final String rawTruststorePassword = properties.get(ProviderProperty.TRUSTSTORE_PASSWORD.getProperty());
|
||||||
|
final String rawTruststoreType = properties.get(ProviderProperty.TRUSTSTORE_TYPE.getProperty());
|
||||||
|
|
||||||
|
final KeyStore trustStore;
|
||||||
|
|
||||||
|
if (rawTruststore == null || rawTruststore.isBlank()) {
|
||||||
|
trustStore = null;
|
||||||
|
} else if (rawTruststorePassword == null) {
|
||||||
|
throw new ProviderCreationException("Truststore Password not configured");
|
||||||
|
} else {
|
||||||
|
final StandardKeyStoreBuilder builder = new StandardKeyStoreBuilder();
|
||||||
|
builder.type(rawTruststoreType);
|
||||||
|
|
||||||
|
final char[] trustStorePassword = rawTruststorePassword.toCharArray();
|
||||||
|
builder.password(trustStorePassword);
|
||||||
|
|
||||||
|
final Path trustStorePath = Paths.get(rawTruststore);
|
||||||
|
try (InputStream trustStoreStream = Files.newInputStream(trustStorePath)) {
|
||||||
|
builder.inputStream(trustStoreStream);
|
||||||
|
trustStore = builder.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return trustStore;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,6 @@ package org.apache.nifi.ldap.tenants;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||||
import org.apache.nifi.authentication.exception.ProviderCreationException;
|
|
||||||
import org.apache.nifi.authentication.exception.ProviderDestructionException;
|
import org.apache.nifi.authentication.exception.ProviderDestructionException;
|
||||||
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
|
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
|
||||||
import org.apache.nifi.authorization.Group;
|
import org.apache.nifi.authorization.Group;
|
||||||
|
@ -34,10 +33,9 @@ import org.apache.nifi.authorization.util.IdentityMappingUtil;
|
||||||
import org.apache.nifi.components.PropertyValue;
|
import org.apache.nifi.components.PropertyValue;
|
||||||
import org.apache.nifi.ldap.LdapAuthenticationStrategy;
|
import org.apache.nifi.ldap.LdapAuthenticationStrategy;
|
||||||
import org.apache.nifi.ldap.LdapsSocketFactory;
|
import org.apache.nifi.ldap.LdapsSocketFactory;
|
||||||
import org.apache.nifi.ldap.ProviderProperty;
|
|
||||||
import org.apache.nifi.ldap.ReferralStrategy;
|
import org.apache.nifi.ldap.ReferralStrategy;
|
||||||
import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
|
import org.apache.nifi.ldap.ssl.LdapSslContextProvider;
|
||||||
import org.apache.nifi.security.ssl.StandardSslContextBuilder;
|
import org.apache.nifi.ldap.ssl.StandardLdapSslContextProvider;
|
||||||
import org.apache.nifi.util.FormatUtils;
|
import org.apache.nifi.util.FormatUtils;
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
import org.apache.nifi.util.NiFiProperties;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -65,12 +63,6 @@ import javax.naming.NamingException;
|
||||||
import javax.naming.directory.Attribute;
|
import javax.naming.directory.Attribute;
|
||||||
import javax.naming.directory.SearchControls;
|
import javax.naming.directory.SearchControls;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -835,91 +827,8 @@ public class LdapUserGroupProvider implements UserGroupProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SSLContext getConfiguredSslContext(final AuthorizerConfigurationContext configurationContext) {
|
private SSLContext getConfiguredSslContext(final AuthorizerConfigurationContext configurationContext) {
|
||||||
final String rawProtocol = configurationContext.getProperty(ProviderProperty.TLS_PROTOCOL.getProperty()).getValue();
|
final LdapSslContextProvider ldapSslContextProvider = new StandardLdapSslContextProvider();
|
||||||
|
final Map<String, String> contextProperties = configurationContext.getProperties();
|
||||||
SSLContext sslContext = null;
|
return ldapSslContextProvider.createContext(contextProperties);
|
||||||
try {
|
|
||||||
final KeyStore trustStore = getTrustStore(configurationContext);
|
|
||||||
if (trustStore == null) {
|
|
||||||
logger.debug("Truststore not configured");
|
|
||||||
} else {
|
|
||||||
final StandardSslContextBuilder sslContextBuilder = new StandardSslContextBuilder();
|
|
||||||
sslContextBuilder.protocol(rawProtocol);
|
|
||||||
sslContextBuilder.trustStore(trustStore);
|
|
||||||
|
|
||||||
final KeyStore keyStore = getKeyStore(configurationContext);
|
|
||||||
if (keyStore == null) {
|
|
||||||
logger.debug("Keystore not configured");
|
|
||||||
} else {
|
|
||||||
final String keyStorePassword = configurationContext.getProperty(ProviderProperty.KEYSTORE_PASSWORD.getProperty()).getValue();
|
|
||||||
final char[] keyPassword = keyStorePassword.toCharArray();
|
|
||||||
|
|
||||||
sslContextBuilder.keyStore(keyStore);
|
|
||||||
sslContextBuilder.keyPassword(keyPassword);
|
|
||||||
sslContext = sslContextBuilder.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
|
||||||
logger.error("Encountered an error configuring TLS for LDAP user group provider: {}", e.getLocalizedMessage());
|
|
||||||
throw new ProviderCreationException("Error configuring TLS for LDAP user group provider", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sslContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static KeyStore getKeyStore(final AuthorizerConfigurationContext configurationContext) throws IOException {
|
|
||||||
final String rawKeystore = configurationContext.getProperty(ProviderProperty.KEYSTORE.getProperty()).getValue();
|
|
||||||
final String rawKeystorePassword = configurationContext.getProperty(ProviderProperty.KEYSTORE_PASSWORD.getProperty()).getValue();
|
|
||||||
final String rawKeystoreType = configurationContext.getProperty(ProviderProperty.KEYSTORE_TYPE.getProperty()).getValue();
|
|
||||||
|
|
||||||
final KeyStore keyStore;
|
|
||||||
|
|
||||||
if (rawKeystore == null || rawKeystore.isBlank()) {
|
|
||||||
keyStore = null;
|
|
||||||
} else if (rawKeystorePassword == null) {
|
|
||||||
throw new ProviderCreationException("Keystore Password not configured");
|
|
||||||
} else {
|
|
||||||
final StandardKeyStoreBuilder builder = new StandardKeyStoreBuilder();
|
|
||||||
builder.type(rawKeystoreType);
|
|
||||||
|
|
||||||
final char[] keyStorePassword = rawKeystorePassword.toCharArray();
|
|
||||||
builder.password(keyStorePassword);
|
|
||||||
|
|
||||||
final Path trustStorePath = Paths.get(rawKeystore);
|
|
||||||
try (InputStream trustStoreStream = Files.newInputStream(trustStorePath)) {
|
|
||||||
builder.inputStream(trustStoreStream);
|
|
||||||
keyStore = builder.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return keyStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static KeyStore getTrustStore(final AuthorizerConfigurationContext configurationContext) throws IOException {
|
|
||||||
final String rawTruststore = configurationContext.getProperty(ProviderProperty.TRUSTSTORE.getProperty()).getValue();
|
|
||||||
final String rawTruststorePassword = configurationContext.getProperty(ProviderProperty.TRUSTSTORE_PASSWORD.getProperty()).getValue();
|
|
||||||
final String rawTruststoreType = configurationContext.getProperty(ProviderProperty.TRUSTSTORE_TYPE.getProperty()).getValue();
|
|
||||||
|
|
||||||
final KeyStore trustStore;
|
|
||||||
|
|
||||||
if (rawTruststore == null || rawTruststore.isBlank()) {
|
|
||||||
trustStore = null;
|
|
||||||
} else if (rawTruststorePassword == null) {
|
|
||||||
throw new ProviderCreationException("Truststore Password not configured");
|
|
||||||
} else {
|
|
||||||
final StandardKeyStoreBuilder builder = new StandardKeyStoreBuilder();
|
|
||||||
builder.type(rawTruststoreType);
|
|
||||||
|
|
||||||
final char[] trustStorePassword = rawTruststorePassword.toCharArray();
|
|
||||||
builder.password(trustStorePassword);
|
|
||||||
|
|
||||||
final Path trustStorePath = Paths.get(rawTruststore);
|
|
||||||
try (InputStream trustStoreStream = Files.newInputStream(trustStorePath)) {
|
|
||||||
builder.inputStream(trustStoreStream);
|
|
||||||
trustStore = builder.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return trustStore;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
* 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.ldap.ssl;
|
||||||
|
|
||||||
|
import org.apache.nifi.ldap.ProviderProperty;
|
||||||
|
import org.apache.nifi.security.cert.builder.StandardCertificateBuilder;
|
||||||
|
import org.apache.nifi.security.ssl.EphemeralKeyStoreBuilder;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.security.auth.x500.X500Principal;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
class StandardLdapSslContextProviderTest {
|
||||||
|
|
||||||
|
private static final String TLS_PROTOCOL = "TLS";
|
||||||
|
|
||||||
|
private static final String ALIAS = "entry-0";
|
||||||
|
|
||||||
|
private static final String KEY_STORE_EXTENSION = ".p12";
|
||||||
|
|
||||||
|
private static final String KEY_STORE_PASS = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
private static final String TRUST_STORE_PASS = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
@TempDir
|
||||||
|
private static Path keyStoreDirectory;
|
||||||
|
|
||||||
|
private static String keyStoreType;
|
||||||
|
|
||||||
|
private static Path keyStorePath;
|
||||||
|
|
||||||
|
private static String trustStoreType;
|
||||||
|
|
||||||
|
private static Path trustStorePath;
|
||||||
|
|
||||||
|
private StandardLdapSslContextProvider provider;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void setConfiguration() throws Exception {
|
||||||
|
final KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
|
||||||
|
final X509Certificate certificate = new StandardCertificateBuilder(keyPair, new X500Principal("CN=localhost"), Duration.ofHours(1)).build();
|
||||||
|
final KeyStore keyStore = new EphemeralKeyStoreBuilder().build();
|
||||||
|
keyStore.setKeyEntry(ALIAS, keyPair.getPrivate(), KEY_STORE_PASS.toCharArray(), new Certificate[]{certificate});
|
||||||
|
|
||||||
|
keyStorePath = Files.createTempFile(keyStoreDirectory, "keyStore", KEY_STORE_EXTENSION);
|
||||||
|
try (OutputStream outputStream = Files.newOutputStream(keyStorePath)) {
|
||||||
|
keyStore.store(outputStream, KEY_STORE_PASS.toCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
keyStoreType = keyStore.getType().toUpperCase();
|
||||||
|
|
||||||
|
final KeyStore trustStore = new EphemeralKeyStoreBuilder().addCertificate(certificate).build();
|
||||||
|
trustStorePath = Files.createTempFile(keyStoreDirectory, "trustStore", KEY_STORE_EXTENSION);
|
||||||
|
try (OutputStream outputStream = Files.newOutputStream(trustStorePath)) {
|
||||||
|
trustStore.store(outputStream, TRUST_STORE_PASS.toCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
trustStoreType = trustStore.getType().toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setProvider() {
|
||||||
|
provider = new StandardLdapSslContextProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreateContextEmptyProperties() {
|
||||||
|
final SSLContext sslContext = provider.createContext(Map.of());
|
||||||
|
|
||||||
|
assertNotNull(sslContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreateContextProtocol() {
|
||||||
|
final Map<String, String> properties = Map.of(
|
||||||
|
ProviderProperty.TLS_PROTOCOL.getProperty(), TLS_PROTOCOL
|
||||||
|
);
|
||||||
|
|
||||||
|
final SSLContext sslContext = provider.createContext(properties);
|
||||||
|
|
||||||
|
assertNotNull(sslContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreateContextTrustStore() {
|
||||||
|
final Map<String, String> properties = Map.of(
|
||||||
|
ProviderProperty.TLS_PROTOCOL.getProperty(), TLS_PROTOCOL,
|
||||||
|
ProviderProperty.TRUSTSTORE.getProperty(), trustStorePath.toString(),
|
||||||
|
ProviderProperty.TRUSTSTORE_TYPE.getProperty(), trustStoreType,
|
||||||
|
ProviderProperty.TRUSTSTORE_PASSWORD.getProperty(), TRUST_STORE_PASS
|
||||||
|
);
|
||||||
|
|
||||||
|
final SSLContext sslContext = provider.createContext(properties);
|
||||||
|
|
||||||
|
assertNotNull(sslContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreateContextKeyStore() {
|
||||||
|
final Map<String, String> properties = Map.of(
|
||||||
|
ProviderProperty.TLS_PROTOCOL.getProperty(), TLS_PROTOCOL,
|
||||||
|
ProviderProperty.KEYSTORE.getProperty(), keyStorePath.toString(),
|
||||||
|
ProviderProperty.KEYSTORE_TYPE.getProperty(), keyStoreType,
|
||||||
|
ProviderProperty.KEYSTORE_PASSWORD.getProperty(), KEY_STORE_PASS
|
||||||
|
);
|
||||||
|
|
||||||
|
final SSLContext sslContext = provider.createContext(properties);
|
||||||
|
|
||||||
|
assertNotNull(sslContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreateContext() {
|
||||||
|
final Map<String, String> properties = Map.of(
|
||||||
|
ProviderProperty.TLS_PROTOCOL.getProperty(), TLS_PROTOCOL,
|
||||||
|
ProviderProperty.TRUSTSTORE.getProperty(), trustStorePath.toString(),
|
||||||
|
ProviderProperty.TRUSTSTORE_TYPE.getProperty(), trustStoreType,
|
||||||
|
ProviderProperty.TRUSTSTORE_PASSWORD.getProperty(), TRUST_STORE_PASS,
|
||||||
|
ProviderProperty.KEYSTORE.getProperty(), keyStorePath.toString(),
|
||||||
|
ProviderProperty.KEYSTORE_TYPE.getProperty(), keyStoreType,
|
||||||
|
ProviderProperty.KEYSTORE_PASSWORD.getProperty(), KEY_STORE_PASS
|
||||||
|
);
|
||||||
|
|
||||||
|
final SSLContext sslContext = provider.createContext(properties);
|
||||||
|
|
||||||
|
assertNotNull(sslContext);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue