You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by al...@apache.org on 2016/12/02 20:39:19 UTC
nifi git commit: NIFI-2325: - Adding support for LDAPS.
Repository: nifi
Updated Branches:
refs/heads/master 316cae16d -> c5ef07678
NIFI-2325:
- Adding support for LDAPS.
This closes #1275.
Signed-off-by: Andy LoPresto <al...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/c5ef0767
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/c5ef0767
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/c5ef0767
Branch: refs/heads/master
Commit: c5ef0767864b90ee9a013a60405c08ce6192d2bc
Parents: 316cae1
Author: Matt Gilman <ma...@gmail.com>
Authored: Mon Nov 28 16:38:33 2016 -0500
Committer: Andy LoPresto <al...@apache.org>
Committed: Fri Dec 2 12:41:03 2016 -0800
----------------------------------------------------------------------
.../src/main/asciidoc/administration-guide.adoc | 18 +--
.../resources/conf/login-identity-providers.xml | 18 +--
.../nifi/ldap/LdapAuthenticationStrategy.java | 1 +
.../java/org/apache/nifi/ldap/LdapProvider.java | 121 ++++++++++++-------
.../apache/nifi/ldap/LdapsSocketFactory.java | 106 ++++++++++++++++
5 files changed, 200 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/nifi/blob/c5ef0767/nifi-docs/src/main/asciidoc/administration-guide.adoc
----------------------------------------------------------------------
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index 773cb64..ccbd471 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -307,17 +307,17 @@ nifi.security.user.login.identity.provider=ldap-provider
[options="header,footer"]
|==================================================================================================================================================
| Property Name | Description
-|`Authentication Strategy` | How the connection to the LDAP server is authenticated. Possible values are ANONYMOUS, SIMPLE, or START_TLS.
+|`Authentication Strategy` | How the connection to the LDAP server is authenticated. Possible values are ANONYMOUS, SIMPLE, LDAPS, 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 - Keystore` | Path to the Keystore that is used when connecting to LDAP using LDAPS or START_TLS.
+|`TLS - Keystore Password` | Password for the Keystore that is used when connecting to LDAP using LDAPS or START_TLS.
+|`TLS - Keystore Type` | Type of the Keystore that is used when connecting to LDAP using LDAPS or START_TLS (i.e. JKS or PKCS12).
+|`TLS - Truststore` | Path to the Truststore that is used when connecting to LDAP using LDAPS or START_TLS.
+|`TLS - Truststore Password` | Password for the Truststore that is used when connecting to LDAP using LDAPS or START_TLS.
+|`TLS - Truststore Type` | Type of the Truststore that is used when connecting to LDAP using LDAPS or START_TLS (i.e. JKS or PKCS12).
+|`TLS - Client Auth` | Client authentication policy when connecting to LDAP using LDAPS or START_TLS. Possible values are REQUIRED, WANT, NONE.
+|`TLS - Protocol` | Protocol to use when connecting to LDAP using LDAPS or 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).
http://git-wip-us.apache.org/repos/asf/nifi/blob/c5ef0767/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/login-identity-providers.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/login-identity-providers.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/login-identity-providers.xml
index 828868a..fbfcfb4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/login-identity-providers.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/login-identity-providers.xml
@@ -23,25 +23,25 @@
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.
+ values are ANONYMOUS, SIMPLE, LDAPS, 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' - Path to the Keystore that is used when connecting to LDAP using LDAPS or START_TLS.
'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
- using START_TLS.
+ using LDAPS or 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.
+ LDAPS or START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using LDAPS or START_TLS.
'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
- LDAP using START_TLS.
+ LDAP using LDAPS or 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.
+ LDAPS or START_TLS (i.e. JKS or PKCS12).
+ 'TLS - Client Auth' - Client authentication policy when connecting to LDAP using LDAPS or START_TLS.
Possible values are REQUIRED, WANT, NONE.
- 'TLS - Protocol' - Protocol to use when connecting to LDAP using START_TLS. (i.e. TLS,
+ 'TLS - Protocol' - Protocol to use when connecting to LDAP using LDAPS or 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.
http://git-wip-us.apache.org/repos/asf/nifi/blob/c5ef0767/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapAuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapAuthenticationStrategy.java b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapAuthenticationStrategy.java
index 7124ce1..fc64c40 100644
--- a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapAuthenticationStrategy.java
+++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapAuthenticationStrategy.java
@@ -23,5 +23,6 @@ public enum LdapAuthenticationStrategy {
ANONYMOUS,
SIMPLE,
+ LDAPS,
START_TLS
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/c5ef0767/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapProvider.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapProvider.java b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapProvider.java
index 4338783..851cf0d 100644
--- a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapProvider.java
+++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapProvider.java
@@ -47,6 +47,7 @@ import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
import org.springframework.security.ldap.search.LdapUserSearch;
import org.springframework.security.ldap.userdetails.LdapUserDetails;
+import javax.naming.Context;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.KeyManagementException;
@@ -96,11 +97,6 @@ public class LdapProvider implements LoginIdentityProvider {
setTimeout(configurationContext, baseEnvironment, "Connect Timeout", "com.sun.jndi.ldap.connect.timeout");
setTimeout(configurationContext, baseEnvironment, "Read Timeout", "com.sun.jndi.ldap.read.timeout");
- // set the base environment is necessary
- if (!baseEnvironment.isEmpty()) {
- context.setBaseEnvironmentProperties(baseEnvironment);
- }
-
// authentication strategy
final String rawAuthenticationStrategy = configurationContext.getProperty("Authentication Strategy");
final LdapAuthenticationStrategy authenticationStrategy;
@@ -126,6 +122,20 @@ public class LdapProvider implements LoginIdentityProvider {
case SIMPLE:
context.setAuthenticationStrategy(new SimpleDirContextAuthenticationStrategy());
break;
+ case LDAPS:
+ context.setAuthenticationStrategy(new SimpleDirContextAuthenticationStrategy());
+
+ // indicate a secure connection
+ baseEnvironment.put(Context.SECURITY_PROTOCOL, "ssl");
+
+ // get the configured ssl context
+ final SSLContext ldapsSslContext = getConfiguredSslContext(configurationContext);
+ if (ldapsSslContext != null) {
+ // initialize the ldaps socket factory prior to use
+ LdapsSocketFactory.initialize(ldapsSslContext.getSocketFactory());
+ baseEnvironment.put("java.naming.ldap.factory.socket", LdapsSocketFactory.class.getName());
+ }
+ break;
case START_TLS:
final AbstractTlsDirContextAuthenticationStrategy tlsAuthenticationStrategy = new DefaultTlsDirContextAuthenticationStrategy();
@@ -136,49 +146,13 @@ public class LdapProvider implements LoginIdentityProvider {
tlsAuthenticationStrategy.setShutdownTlsGracefully(shutdownGracefully);
}
- final String rawKeystore = configurationContext.getProperty("TLS - Keystore");
- final String rawKeystorePassword = configurationContext.getProperty("TLS - Keystore Password");
- final String rawKeystoreType = configurationContext.getProperty("TLS - Keystore Type");
- final String rawTruststore = configurationContext.getProperty("TLS - Truststore");
- final String rawTruststorePassword = configurationContext.getProperty("TLS - Truststore Password");
- final String rawTruststoreType = configurationContext.getProperty("TLS - Truststore Type");
- final String rawClientAuth = configurationContext.getProperty("TLS - Client Auth");
- final String rawProtocol = configurationContext.getProperty("TLS - Protocol");
-
- final ClientAuth clientAuth;
- if (StringUtils.isBlank(rawClientAuth)) {
- clientAuth = ClientAuth.NONE;
- } else {
- try {
- clientAuth = ClientAuth.valueOf(rawClientAuth);
- } catch (final IllegalArgumentException iae) {
- throw new ProviderCreationException(String.format("Unrecognized client auth '%s'. Possible values are [%s]",
- rawClientAuth, StringUtils.join(ClientAuth.values(), ", ")));
- }
- }
-
- // ensure the protocol is specified
- if (StringUtils.isBlank(rawProtocol)) {
- throw new ProviderCreationException("TLS - Protocol must be specified.");
- }
-
- try {
- final SSLContext sslContext;
- if (StringUtils.isBlank(rawKeystore)) {
- sslContext = SslContextFactory.createTrustSslContext(rawTruststore, rawTruststorePassword.toCharArray(), rawTruststoreType, rawProtocol);
- } else {
- if (StringUtils.isBlank(rawTruststore)) {
- sslContext = SslContextFactory.createSslContext(rawKeystore, rawKeystorePassword.toCharArray(), rawKeystoreType, rawProtocol);
- } else {
- sslContext = SslContextFactory.createSslContext(rawKeystore, rawKeystorePassword.toCharArray(), rawKeystoreType,
- rawTruststore, rawTruststorePassword.toCharArray(), rawTruststoreType, clientAuth, rawProtocol);
- }
- }
- tlsAuthenticationStrategy.setSslSocketFactory(sslContext.getSocketFactory());
- } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | KeyManagementException | IOException e) {
- throw new ProviderCreationException(e.getMessage(), e);
+ // get the configured ssl context
+ final SSLContext startTlsSslContext = getConfiguredSslContext(configurationContext);
+ if (startTlsSslContext != null) {
+ tlsAuthenticationStrategy.setSslSocketFactory(startTlsSslContext.getSocketFactory());
}
+ // set the authentication strategy
context.setAuthenticationStrategy(tlsAuthenticationStrategy);
break;
}
@@ -241,6 +215,11 @@ public class LdapProvider implements LoginIdentityProvider {
}
}
+ // set the base environment is necessary
+ if (!baseEnvironment.isEmpty()) {
+ context.setBaseEnvironmentProperties(baseEnvironment);
+ }
+
try {
// handling initializing beans
context.afterPropertiesSet();
@@ -269,6 +248,56 @@ public class LdapProvider implements LoginIdentityProvider {
}
}
+ private SSLContext getConfiguredSslContext(final LoginIdentityProviderConfigurationContext configurationContext) {
+ final String rawKeystore = configurationContext.getProperty("TLS - Keystore");
+ final String rawKeystorePassword = configurationContext.getProperty("TLS - Keystore Password");
+ final String rawKeystoreType = configurationContext.getProperty("TLS - Keystore Type");
+ final String rawTruststore = configurationContext.getProperty("TLS - Truststore");
+ final String rawTruststorePassword = configurationContext.getProperty("TLS - Truststore Password");
+ final String rawTruststoreType = configurationContext.getProperty("TLS - Truststore Type");
+ final String rawClientAuth = configurationContext.getProperty("TLS - Client Auth");
+ final String rawProtocol = configurationContext.getProperty("TLS - Protocol");
+
+ // create the ssl context
+ final SSLContext sslContext;
+ try {
+ if (StringUtils.isBlank(rawKeystore) && StringUtils.isBlank(rawTruststore)) {
+ sslContext = null;
+ } else {
+ // ensure the protocol is specified
+ if (StringUtils.isBlank(rawProtocol)) {
+ throw new ProviderCreationException("TLS - Protocol must be specified.");
+ }
+
+ if (StringUtils.isBlank(rawKeystore)) {
+ sslContext = SslContextFactory.createTrustSslContext(rawTruststore, rawTruststorePassword.toCharArray(), rawTruststoreType, rawProtocol);
+ } else if (StringUtils.isBlank(rawTruststore)) {
+ sslContext = SslContextFactory.createSslContext(rawKeystore, rawKeystorePassword.toCharArray(), rawKeystoreType, rawProtocol);
+ } else {
+ // determine the client auth if specified
+ final ClientAuth clientAuth;
+ if (StringUtils.isBlank(rawClientAuth)) {
+ clientAuth = ClientAuth.NONE;
+ } else {
+ try {
+ clientAuth = ClientAuth.valueOf(rawClientAuth);
+ } catch (final IllegalArgumentException iae) {
+ throw new ProviderCreationException(String.format("Unrecognized client auth '%s'. Possible values are [%s]",
+ rawClientAuth, StringUtils.join(ClientAuth.values(), ", ")));
+ }
+ }
+
+ sslContext = SslContextFactory.createSslContext(rawKeystore, rawKeystorePassword.toCharArray(), rawKeystoreType,
+ rawTruststore, rawTruststorePassword.toCharArray(), rawTruststoreType, clientAuth, rawProtocol);
+ }
+ }
+ } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | KeyManagementException | IOException e) {
+ throw new ProviderCreationException(e.getMessage(), e);
+ }
+
+ return sslContext;
+ }
+
@Override
public final AuthenticationResponse authenticate(final LoginCredentials credentials) throws InvalidLoginCredentialsException, IdentityAccessException {
if (provider == null) {
http://git-wip-us.apache.org/repos/asf/nifi/blob/c5ef0767/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapsSocketFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapsSocketFactory.java b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapsSocketFactory.java
new file mode 100644
index 0000000..7c4eb87
--- /dev/null
+++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapsSocketFactory.java
@@ -0,0 +1,106 @@
+/*
+ * 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;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+/**
+ * SSLSocketFactory used when connecting to a Directory Server over LDAPS.
+ */
+public class LdapsSocketFactory extends SSLSocketFactory {
+
+ // singleton
+ private static LdapsSocketFactory instance;
+
+ // delegate
+ private SSLSocketFactory delegate;
+
+ /**
+ * Initializes the LdapsSocketFactory with the specified SSLSocketFactory. The specified
+ * socket factory will be used as a delegate for all subsequent instances of this class.
+ *
+ * @param sslSocketFactory delegate socket factory
+ */
+ public static void initialize(final SSLSocketFactory sslSocketFactory) {
+ instance = new LdapsSocketFactory(sslSocketFactory);
+ }
+
+ /**
+ * Gets the LdapsSocketFactory that was previously initialized.
+ *
+ * @return socket factory
+ */
+ public static SocketFactory getDefault() {
+ return instance;
+ }
+
+ /**
+ * Creates a new LdapsSocketFactory.
+ *
+ * @param sslSocketFactory delegate socket factory
+ */
+ private LdapsSocketFactory(final SSLSocketFactory sslSocketFactory) {
+ delegate = sslSocketFactory;
+ }
+
+ // delegate methods
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ return delegate.getSupportedCipherSuites();
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites() {
+ return delegate.getDefaultCipherSuites();
+ }
+
+ @Override
+ public Socket createSocket(Socket socket, String string, int i, boolean bln) throws IOException {
+ return delegate.createSocket(socket, string, i, bln);
+ }
+
+ @Override
+ public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException {
+ return delegate.createSocket(ia, i, ia1, i1);
+ }
+
+ @Override
+ public Socket createSocket(InetAddress ia, int i) throws IOException {
+ return delegate.createSocket(ia, i);
+ }
+
+ @Override
+ public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException, UnknownHostException {
+ return delegate.createSocket(string, i, ia, i1);
+ }
+
+ @Override
+ public Socket createSocket(String string, int i) throws IOException, UnknownHostException {
+ return delegate.createSocket(string, i);
+ }
+
+ @Override
+ public Socket createSocket() throws IOException {
+ return delegate.createSocket();
+ }
+}