Repository: nifi
Updated Branches:
  refs/heads/NIFI-655 0281e2773 -> cfee612a7


NIFI-655:
- Initial commit of the LDAP based identity providers.
- Fixed issue when attempting to log into a NiFi that does not support new 
account requests.

Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/cfee612a
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/cfee612a
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/cfee612a

Branch: refs/heads/NIFI-655
Commit: cfee612a78e4256fc0295e6ad1315ba26996ed94
Parents: 0281e27
Author: Matt Gilman <[email protected]>
Authored: Wed Nov 11 19:40:40 2015 -0500
Committer: Matt Gilman <[email protected]>
Committed: Wed Nov 11 19:40:40 2015 -0500

----------------------------------------------------------------------
 nifi-assembly/pom.xml                           |   5 +
 .../login/LoginAuthenticationFilter.java        |   2 +-
 .../src/main/webapp/js/nf/canvas/nf-canvas.js   |   2 +-
 .../src/main/webapp/js/nf/login/nf-login.js     |  37 ++++-
 .../nifi-ldap-iaa-providers-nar/pom.xml         |  32 ++++
 .../nifi-ldap-iaa-providers/pom.xml             |  56 +++++++
 .../apache/nifi/ldap/AbstractLdapProvider.java  |  80 ++++++++++
 .../nifi/ldap/ActiveDirectoryProvider.java      |  46 ++++++
 .../nifi/ldap/LdapAuthenticationStrategy.java   |  27 ++++
 .../java/org/apache/nifi/ldap/LdapProvider.java | 151 +++++++++++++++++++
 ...he.nifi.authentication.LoginIdentityProvider |  16 ++
 .../nifi-ldap-iaa-providers-bundle/pom.xml      |  38 +++++
 nifi-nar-bundles/pom.xml                        |   1 +
 pom.xml                                         |  67 +++++---
 14 files changed, 532 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-assembly/pom.xml b/nifi-assembly/pom.xml
index 254dff0..db0a083 100644
--- a/nifi-assembly/pom.xml
+++ b/nifi-assembly/pom.xml
@@ -174,6 +174,11 @@ language governing permissions and limitations under the 
License. -->
         </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-ldap-iaa-providers-nar</artifactId>
+            <type>nar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-dbcp-service-nar</artifactId>
             <type>nar</type>
         </dependency>

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/LoginAuthenticationFilter.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/LoginAuthenticationFilter.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/LoginAuthenticationFilter.java
index 1e68d16..5c3b3e6 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/LoginAuthenticationFilter.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/login/LoginAuthenticationFilter.java
@@ -205,7 +205,7 @@ public class LoginAuthenticationFilter extends 
AbstractAuthenticationProcessingF
         } else {
             response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
         }
-        
+
         response.setContentType("text/plain");
 
         final PrintWriter out = response.getWriter();

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
index c316ef2..894ade8 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
@@ -1071,7 +1071,7 @@ nf.Canvas = (function () {
                     deferred.resolve();
                 }).fail(function (xhr, status, error) {
                     // there is no anonymous access and we don't know this 
user - open the login page which handles login/registration/etc
-                    if (xhr.status === 401) {
+                    if (xhr.status === 401 || xhr.status === 403) {
                         window.location = '/nifi/login';
                     } else {
                         deferred.reject(xhr, status, error);

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
index 12f7ed7..f844d91 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/login/nf-login.js
@@ -45,11 +45,11 @@ nf.Login = (function () {
         $('#username').val('');
         $('#password').val('');
         $('#login-submission-button').text('Log in');
-        
+
         // update the form visibility
         $('#login-container').show();
         $('#nifi-registration-container').hide();
-        
+
         // set the focus
         $('#username').focus();
     };
@@ -69,7 +69,7 @@ nf.Login = (function () {
         // reset the forms
         $('#login-submission-button').text('Submit');
         $('#nifi-registration-justification').val('');
-        
+
         // update the form visibility
         $('#login-container').hide();
         $('#nifi-registration-container').show();
@@ -99,7 +99,7 @@ nf.Login = (function () {
         }).done(function (jwt) {
             // store the jwt and reload the page
             nf.Storage.setItem('jwt', jwt);
-            
+
             // check to see if they actually have access now
             $.ajax({
                 type: 'GET',
@@ -112,7 +112,7 @@ nf.Login = (function () {
                     // show the user
                     var user = getJwtSubject(jwt);
                     $('#nifi-user-submit-justification').text(user);
-            
+
                     // show the registration form
                     initializeNiFiRegistration();
                     showNiFiRegistration();
@@ -130,7 +130,7 @@ nf.Login = (function () {
                 // show the user
                 var user = getJwtSubject(jwt);
                 $('#nifi-user-submit-justification').text(user);
-            
+
                 if (xhr.status === 401) {
                     initializeNiFiRegistration();
                     showNiFiRegistration();
@@ -219,7 +219,7 @@ nf.Login = (function () {
     var logout = function () {
         nf.Storage.removeItem('jwt');
     };
-    
+
     var showLogoutLink = function () {
         $('#user-logout-container').show();
     };
@@ -334,6 +334,29 @@ nf.Login = (function () {
                         }).always(function () {
                             deferred.resolve();
                         });
+                    } else if (xhr.status === 403) {
+                        // attempt to get a token for the current user without 
passing login credentials
+                        token.done(function () {
+                            showMessage = true;
+                            
+                            // the user is logged in with certificate or 
credentials but their account is pending/revoked. error message should indicate
+                            $('#login-message-title').text('Access Denied');
+                            if ($.trim(xhr.responseText) === '') {
+                                $('#login-message').text('Unable to authorize 
you to use this NiFi and anonymous access is disabled.');
+                            } else {
+                                $('#login-message').text(xhr.responseText);
+                            }
+                        }).fail(function (tokenXhr) {
+                            if (tokenXhr.status === 400) {
+                                // no credentials supplied so 400 must be due 
to an invalid/expired token
+                                logout();
+                            }
+
+                            // no token granted, user needs to login with 
their credentials
+                            needsLogin = true;
+                        }).always(function () {
+                            deferred.resolve();
+                        });
                     } else {
                         showMessage = true;
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml
 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml
new file mode 100644
index 0000000..59681b9
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.nifi</groupId>
+        <artifactId>nifi-ldap-iaa-providers-bundle</artifactId>
+        <version>0.3.1-SNAPSHOT</version>
+    </parent>
+    <artifactId>nifi-ldap-iaa-providers-nar</artifactId>
+    <packaging>nar</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-ldap-iaa-providers</artifactId>
+        </dependency>
+    </dependencies>
+    <name>nifi-ldap-iaa-providers-nar</name>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml
 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml
new file mode 100644
index 0000000..9f5b5e8
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml
@@ -0,0 +1,56 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.nifi</groupId>
+        <artifactId>nifi-ldap-iaa-providers-bundle</artifactId>
+        <version>0.3.1-SNAPSHOT</version>
+    </parent>
+    <artifactId>nifi-ldap-iaa-providers</artifactId>
+    <packaging>jar</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-ldap</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-tx</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+    </dependencies>
+    <name>nifi-ldap-iaa-providers</name>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/AbstractLdapProvider.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/AbstractLdapProvider.java
 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/AbstractLdapProvider.java
new file mode 100644
index 0000000..c7f338b
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/AbstractLdapProvider.java
@@ -0,0 +1,80 @@
+/*
+ * 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 org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authentication.LoginCredentials;
+import org.apache.nifi.authentication.LoginIdentityProvider;
+import 
org.apache.nifi.authentication.LoginIdentityProviderConfigurationContext;
+import 
org.apache.nifi.authentication.LoginIdentityProviderInitializationContext;
+import org.apache.nifi.authentication.exception.IdentityAccessException;
+import 
org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
+import org.apache.nifi.authorization.exception.ProviderDestructionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import 
org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.BadCredentialsException;
+import 
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import 
org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider;
+
+/**
+ * Abstract LDAP based implementation of a login identity provider.
+ */
+public abstract class AbstractLdapProvider implements LoginIdentityProvider {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(AbstractLdapProvider.class);
+
+    private AbstractLdapAuthenticationProvider provider;
+
+    @Override
+    public final void initialize(final 
LoginIdentityProviderInitializationContext initializationContext) throws 
ProviderCreationException {
+    }
+
+    @Override
+    public final void onConfigured(final 
LoginIdentityProviderConfigurationContext configurationContext) throws 
ProviderCreationException {
+        System.out.println(Thread.currentThread().getContextClassLoader());
+        provider = getLdapAuthenticationProvider(configurationContext);
+    }
+
+    protected abstract AbstractLdapAuthenticationProvider 
getLdapAuthenticationProvider(LoginIdentityProviderConfigurationContext 
configurationContext) throws ProviderCreationException;
+
+    @Override
+    public final void authenticate(final LoginCredentials credentials) throws 
InvalidLoginCredentialsException, IdentityAccessException {
+        if (provider == null) {
+            throw new IdentityAccessException("The LDAP authentication 
provider is not initialized.");
+        }
+
+        try {
+            final UsernamePasswordAuthenticationToken token = new 
UsernamePasswordAuthenticationToken(credentials.getUsername(), 
credentials.getPassword());
+            provider.authenticate(token);
+        } catch (final AuthenticationServiceException ase) {
+            logger.error(ase.getMessage());
+            if (logger.isDebugEnabled()) {
+                logger.debug(StringUtils.EMPTY, ase);
+            }
+            throw new IdentityAccessException("Unable to query the configured 
directory server. See the logs for additional details.", ase);
+        } catch (final BadCredentialsException bce) {
+            throw new InvalidLoginCredentialsException(bce.getMessage(), bce);
+        }
+    }
+
+    @Override
+    public final void preDestruction() throws ProviderDestructionException {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/ActiveDirectoryProvider.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/ActiveDirectoryProvider.java
 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/ActiveDirectoryProvider.java
new file mode 100644
index 0000000..7be8ec9
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/ActiveDirectoryProvider.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.apache.commons.lang3.StringUtils;
+import 
org.apache.nifi.authentication.LoginIdentityProviderConfigurationContext;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
+import 
org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider;
+import 
org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
+
+/**
+ * Active Directory based implementation of a login identity provider.
+ */
+public class ActiveDirectoryProvider extends AbstractLdapProvider {
+
+    @Override
+    protected AbstractLdapAuthenticationProvider 
getLdapAuthenticationProvider(LoginIdentityProviderConfigurationContext 
configurationContext) throws ProviderCreationException {
+        final String domain = configurationContext.getProperty("Domain");
+        if (StringUtils.isBlank(domain)) {
+            throw new ProviderCreationException("The Active Directory Domain 
must be specified.");
+        }
+
+        final String url = configurationContext.getProperty("Url");
+        if (StringUtils.isBlank(url)) {
+            throw new ProviderCreationException("The Active Directory Url must 
be specified.");
+        }
+
+        final String rootDn = configurationContext.getProperty("Root DN");
+
+        return new ActiveDirectoryLdapAuthenticationProvider(domain, url, 
StringUtils.isBlank(rootDn) ? null : rootDn);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/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
new file mode 100644
index 0000000..a3c4f09
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapAuthenticationStrategy.java
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+/**
+ *
+ */
+public enum LdapAuthenticationStrategy {
+    ANONYMOUS,
+    SIMPLE,
+    DIGEST_MD5,
+    TLS
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/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
new file mode 100644
index 0000000..7d471d5
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapProvider.java
@@ -0,0 +1,151 @@
+/*
+ * 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 java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import javax.net.ssl.SSLContext;
+import org.apache.commons.lang3.StringUtils;
+import 
org.apache.nifi.authentication.LoginIdentityProviderConfigurationContext;
+import org.apache.nifi.authorization.exception.ProviderCreationException;
+import org.apache.nifi.security.util.SslContextFactory;
+import org.apache.nifi.security.util.SslContextFactory.ClientAuth;
+import 
org.springframework.ldap.core.support.AbstractTlsDirContextAuthenticationStrategy;
+import 
org.springframework.ldap.core.support.DefaultTlsDirContextAuthenticationStrategy;
+import 
org.springframework.ldap.core.support.DigestMd5DirContextAuthenticationStrategy;
+import org.springframework.ldap.core.support.LdapContextSource;
+import 
org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy;
+import 
org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider;
+import org.springframework.security.ldap.authentication.BindAuthenticator;
+import 
org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
+import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
+import org.springframework.security.ldap.search.LdapUserSearch;
+
+/**
+ * LDAP based implementation of a login identity provider.
+ */
+public class LdapProvider extends AbstractLdapProvider {
+
+    @Override
+    protected AbstractLdapAuthenticationProvider 
getLdapAuthenticationProvider(LoginIdentityProviderConfigurationContext 
configurationContext) throws ProviderCreationException {
+        final LdapContextSource context = new LdapContextSource();
+
+        final String rawAuthenticationStrategy = 
configurationContext.getProperty("Authentication Strategy");
+        final LdapAuthenticationStrategy authenticationStrategy;
+        try {
+            authenticationStrategy = 
LdapAuthenticationStrategy.valueOf(rawAuthenticationStrategy);
+        } catch (final IllegalArgumentException iae) {
+            throw new ProviderCreationException(String.format("Unrecgonized 
authentication strategy '%s'", rawAuthenticationStrategy));
+        }
+
+        switch (authenticationStrategy) {
+            case ANONYMOUS:
+                context.setAnonymousReadOnly(true);
+                break;
+            default:
+                final String userDn = configurationContext.getProperty("Bind 
DN");
+                final String password = configurationContext.getProperty("Bind 
Password");
+
+                context.setUserDn(userDn);
+                context.setPassword(password);
+
+                switch (authenticationStrategy) {
+                    case SIMPLE:
+                        context.setAuthenticationStrategy(new 
SimpleDirContextAuthenticationStrategy());
+                        break;
+                    case DIGEST_MD5:
+                        context.setAuthenticationStrategy(new 
DigestMd5DirContextAuthenticationStrategy());
+                        break;
+                    case TLS:
+                        final AbstractTlsDirContextAuthenticationStrategy 
tlsAuthenticationStrategy = new DefaultTlsDirContextAuthenticationStrategy();
+
+                        // shutdown gracefully
+                        final String rawShutdownGracefully = 
configurationContext.getProperty("TLS - Shutdown Gracefully");
+                        if (StringUtils.isNotBlank(rawShutdownGracefully)) {
+                            final boolean shutdownGracefully = 
Boolean.TRUE.toString().equalsIgnoreCase(rawShutdownGracefully);
+                            
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");
+
+                        try {
+                            final SSLContext sslContext;
+                            if (StringUtils.isBlank(rawKeystore)) {
+                                sslContext = 
SslContextFactory.createTrustSslContext(rawTruststore, 
rawTruststorePassword.toCharArray(), rawTruststoreType, "TLS");
+                            } else {
+                                if (StringUtils.isBlank(rawTruststore)) {
+                                    sslContext = 
SslContextFactory.createSslContext(rawKeystore, 
rawKeystorePassword.toCharArray(), rawKeystoreType, "TLS");
+                                } else {
+                                    sslContext = 
SslContextFactory.createSslContext(rawKeystore, 
rawKeystorePassword.toCharArray(), rawKeystoreType,
+                                            rawTruststore, 
rawTruststorePassword.toCharArray(), rawTruststoreType, ClientAuth.REQUIRED, 
"TLS");
+                                }
+                            }
+                            
tlsAuthenticationStrategy.setSslSocketFactory(sslContext.getSocketFactory());
+                        } catch (final KeyStoreException | 
NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | 
KeyManagementException | IOException e) {
+                            throw new 
ProviderCreationException(e.getMessage(), e);
+                        }
+
+                        
context.setAuthenticationStrategy(tlsAuthenticationStrategy);
+                        break;
+                }
+                break;
+        }
+
+        final String url = configurationContext.getProperty("Url");
+
+        if (StringUtils.isBlank(url)) {
+            throw new ProviderCreationException("LDAP identity provider 'Url' 
must be specified.");
+        }
+
+        // connection
+        context.setUrl(url);
+
+        final String userSearchBase = configurationContext.getProperty("User 
Search Base");
+        final String userSearchFilter = configurationContext.getProperty("User 
Search Filter");
+
+        if (StringUtils.isBlank(userSearchBase) || 
StringUtils.isBlank(userSearchFilter)) {
+            throw new ProviderCreationException("LDAP identity provider 'User 
Search Base' and 'User Search Filter' must be specified.");
+        }
+
+        // query
+        final LdapUserSearch userSearch = new 
FilterBasedLdapUserSearch(userSearchBase, userSearchFilter, context);
+
+        // bind vs password?
+        final BindAuthenticator authenticator = new BindAuthenticator(context);
+        authenticator.setUserSearch(userSearch);
+
+        try {
+            // handling initializing beans
+            context.afterPropertiesSet();
+            authenticator.afterPropertiesSet();
+        } catch (final Exception e) {
+            throw new ProviderCreationException(e.getMessage(), e);
+        }
+
+        // create the underlying provider
+        return new LdapAuthenticationProvider(authenticator);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider
 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider
new file mode 100644
index 0000000..2158cf7
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider
@@ -0,0 +1,16 @@
+# 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.
+org.apache.nifi.ldap.LdapProvider
+org.apache.nifi.ldap.ActiveDirectoryProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml
new file mode 100644
index 0000000..e038c2c
--- /dev/null
+++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.nifi</groupId>
+        <artifactId>nifi-nar-bundles</artifactId>
+        <version>0.3.1-SNAPSHOT</version>
+    </parent>
+    <artifactId>nifi-ldap-iaa-providers-bundle</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>nifi-ldap-iaa-providers</module>
+        <module>nifi-ldap-iaa-providers-nar</module>
+    </modules>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.nifi</groupId>
+                <artifactId>nifi-ldap-iaa-providers</artifactId>
+                <version>0.3.1-SNAPSHOT</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/nifi-nar-bundles/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/pom.xml b/nifi-nar-bundles/pom.xml
index 841818a..8592b08 100644
--- a/nifi-nar-bundles/pom.xml
+++ b/nifi-nar-bundles/pom.xml
@@ -46,6 +46,7 @@
         <module>nifi-image-bundle</module>
         <module>nifi-avro-bundle</module>
         <module>nifi-couchbase-bundle</module>
+        <module>nifi-ldap-iaa-providers-bundle</module>
     </modules>
     <dependencyManagement>
         <dependencies>

http://git-wip-us.apache.org/repos/asf/nifi/blob/cfee612a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ffb21a8..667ed63 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,14 +1,14 @@
 <?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. -->
+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. -->
 <project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
     <modelVersion>4.0.0</modelVersion>
     <parent>
@@ -91,7 +91,7 @@
         <jetty.version>9.2.11.v20150529</jetty.version>
         <lucene.version>4.10.4</lucene.version>
         <spring.version>4.1.6.RELEASE</spring.version>
-        <spring.security.version>4.0.2.RELEASE</spring.security.version>
+        <spring.security.version>4.0.3.RELEASE</spring.security.version>
         <jersey.version>1.19</jersey.version>
         <hadoop.version>2.6.0</hadoop.version>
         <yammer.metrics.version>2.2.0</yammer.metrics.version>
@@ -251,8 +251,8 @@
                 <version>2.2.1</version>
                 <exclusions>
                     <!-- | Exclude the quartz 2.2.1 bundled version of c3p0 
because it is 
-                        lgpl licensed | We also don't use the JDBC related 
features of quartz for 
-                        which the dependency would matter -->
+                    lgpl licensed | We also don't use the JDBC related 
features of quartz for 
+                    which the dependency would matter -->
                     <exclusion>
                         <groupId>c3p0</groupId>
                         <artifactId>c3p0</artifactId>
@@ -322,7 +322,7 @@
                 <version>${spring.version}</version>
                 <exclusions>
                     <!-- <artifactId>jcl-over-slf4j</artifactId> is used in 
dependencies 
-                        section -->
+                    section -->
                     <exclusion>
                         <groupId>commons-logging</groupId>
                         <artifactId>commons-logging</artifactId>
@@ -465,6 +465,29 @@
                 </exclusions>
             </dependency>
             <dependency>
+                <groupId>org.springframework.security</groupId>
+                <artifactId>spring-security-ldap</artifactId>
+                <version>${spring.security.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>org.springframework</groupId>
+                        <artifactId>spring-core</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.springframework</groupId>
+                        <artifactId>spring-beans</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.springframework</groupId>
+                        <artifactId>spring-context</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.springframework</groupId>
+                        <artifactId>spring-tx</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
                 <groupId>org.aspectj</groupId>
                 <artifactId>aspectjweaver</artifactId>
                 <version>1.8.5</version>
@@ -914,6 +937,12 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
+                <artifactId>nifi-ldap-iaa-providers-nar</artifactId>
+                <version>0.3.1-SNAPSHOT</version>
+                <type>nar</type>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-properties</artifactId>
                 <version>0.3.1-SNAPSHOT</version>
             </dependency>
@@ -1189,7 +1218,7 @@
                                 <module name="OuterTypeFilename" />
                                 <module name="LineLength">
                                     <!-- needs extra, because Eclipse 
formatter ignores the ending left 
-                                        brace -->
+                                    brace -->
                                     <property name="max" value="200" />
                                     <property name="ignorePattern" 
value="^package.*|^import.*|a href|href|http://|https://|ftp://"; />
                                 </module>
@@ -1279,11 +1308,11 @@
     <profiles>
         <profile>
             <!-- Checks style and licensing requirements. This is a good idea 
to run 
-                for contributions and for the release process. While it would 
be nice to 
-                run always these plugins can considerably slow the build and 
have proven 
-                to create unstable builds in our multi-module project and when 
building using 
-                multiple threads. The stability issues seen with Checkstyle in 
multi-module 
-                builds include false-positives and false negatives. -->
+            for contributions and for the release process. While it would be 
nice to 
+            run always these plugins can considerably slow the build and have 
proven 
+            to create unstable builds in our multi-module project and when 
building using 
+            multiple threads. The stability issues seen with Checkstyle in 
multi-module 
+            builds include false-positives and false negatives. -->
             <id>contrib-check</id>
             <build>
                 <plugins>

Reply via email to