You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2015/11/23 21:46:51 UTC
[40/50] [abbrv] nifi git commit: NIFI-655: - Refactoring web security
to use Spring Security Java Configuration. - Introducing security in Web UI
in order to get JWT.
http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-storage.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-storage.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-storage.js
new file mode 100644
index 0000000..7b0c3f6
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-storage.js
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+/* global nf, d3 */
+
+nf.Storage = (function () {
+
+ // Store items for two days before being eligible for removal.
+ var TWO_DAYS = nf.Common.MILLIS_PER_DAY * 2;
+
+ /**
+ * Checks the expiration for the specified entry.
+ *
+ * @param {object} entry
+ * @returns {boolean}
+ */
+ var checkExpiration = function (entry) {
+ if (nf.Common.isDefinedAndNotNull(entry.expires)) {
+ // get the expiration
+ var expires = new Date(entry.expires);
+ var now = new Date();
+
+ // return whether the expiration date has passed
+ return expires.valueOf() < now.valueOf();
+ } else {
+ return false;
+ }
+ };
+
+ /**
+ * Gets an enty for the key. The entry expiration is not checked.
+ *
+ * @param {string} key
+ */
+ var getEntry = function (key) {
+ try {
+ // parse the entry
+ var entry = JSON.parse(localStorage.getItem(key));
+
+ // ensure the entry and item are present
+ if (nf.Common.isDefinedAndNotNull(entry)) {
+ return entry;
+ } else {
+ return null;
+ }
+ } catch (e) {
+ return null;
+ }
+ };
+
+ return {
+ /**
+ * Initializes the storage. Items will be persisted for two days. Once the scripts runs
+ * thereafter, all eligible items will be removed. This strategy does not support persistence.
+ */
+ init: function () {
+ for (var i = 0; i < localStorage.length; i++) {
+ try {
+ // get the next item
+ var key = localStorage.key(i);
+
+ // attempt to get the item which will expire if necessary
+ nf.Storage.getItem(key);
+ } catch (e) {
+ }
+ }
+ },
+
+ /**
+ * Stores the specified item.
+ *
+ * @param {string} key
+ * @param {object} item
+ * @param {integer} expires
+ */
+ setItem: function (key, item, expires) {
+ // calculate the expiration
+ expires = nf.Common.isDefinedAndNotNull(expires) ? expires : new Date().valueOf() + TWO_DAYS;
+
+ // create the entry
+ var entry = {
+ expires: expires,
+ item: item
+ };
+
+ // store the item
+ localStorage.setItem(key, JSON.stringify(entry));
+ },
+
+ /**
+ * Returns whether there is an entry for this key. This will not check the expiration. If
+ * the entry is expired, it will return null on a subsequent getItem invocation.
+ *
+ * @param {string} key
+ * @returns {boolean}
+ */
+ hasItem: function (key) {
+ return getEntry(key) !== null;
+ },
+
+ /**
+ * Gets the item with the specified key. If an item with this key does
+ * not exist, null is returned. If an item exists but cannot be parsed
+ * or is malformed/unrecognized, null is returned.
+ *
+ * @param {type} key
+ */
+ getItem: function (key) {
+ var entry = getEntry(key);
+ if (entry === null) {
+ return null;
+ }
+
+ // if the entry is expired, drop it and return null
+ if (checkExpiration(entry)) {
+ nf.Storage.removeItem(key);
+ return null;
+ }
+
+ // if the entry has the specified field return its value
+ if (nf.Common.isDefinedAndNotNull(entry['item'])) {
+ return entry['item'];
+ } else {
+ return null;
+ }
+ },
+
+ /**
+ * Gets the expiration for the specified item. This will not check the expiration. If
+ * the entry is expired, it will return null on a subsequent getItem invocation.
+ *
+ * @param {string} key
+ * @returns {integer}
+ */
+ getItemExpiration: function (key) {
+ var entry = getEntry(key);
+ if (entry === null) {
+ return null;
+ }
+
+ // if the entry has the specified field return its value
+ if (nf.Common.isDefinedAndNotNull(entry['expires'])) {
+ return entry['expires'];
+ } else {
+ return null;
+ }
+ },
+
+ /**
+ * Removes the item with the specified key.
+ *
+ * @param {type} key
+ */
+ removeItem: function (key) {
+ localStorage.removeItem(key);
+ }
+ };
+}());
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance.js
index 0edbe08..876e06d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance.js
@@ -174,6 +174,8 @@ nf.Provenance = (function () {
* Initializes the status page.
*/
init: function () {
+ nf.Storage.init();
+
// load the users authorities and detect if the NiFi is clustered
$.when(loadControllerConfig(), loadAuthorities(), detectedCluster()).done(function () {
// create the provenance table
http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
index 97f8626..4f06662 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary.js
@@ -128,6 +128,8 @@ nf.Summary = (function () {
* Initializes the status page.
*/
init: function () {
+ nf.Storage.init();
+
// intialize the summary table
initializeSummaryTable().done(function () {
// load the table
http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/templates/nf-templates.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/templates/nf-templates.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/templates/nf-templates.js
index b55bee2..678e352 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/templates/nf-templates.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/templates/nf-templates.js
@@ -204,6 +204,8 @@ nf.Templates = (function () {
* Initializes the templates page.
*/
init: function () {
+ nf.Storage.init();
+
// load the users authorities
loadAuthorities().done(function () {
http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users.js
index 96f73a5..9364aec 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/users/nf-users.js
@@ -116,6 +116,8 @@ nf.Users = (function () {
* Initializes the counters page.
*/
init: function () {
+ nf.Storage.init();
+
// load the users authorities
loadAuthorities().done(function () {
// create the counters table
http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/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/aaf14c45/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..5cbd6f9
--- /dev/null
+++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml
@@ -0,0 +1,60 @@
+<?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-utils</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/aaf14c45/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..7124ce1
--- /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,
+ START_TLS
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/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..4dc7ea4
--- /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,279 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLContext;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authentication.AuthenticationResponse;
+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.apache.nifi.security.util.SslContextFactory;
+import org.apache.nifi.security.util.SslContextFactory.ClientAuth;
+import org.apache.nifi.util.FormatUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.ldap.CommunicationException;
+import org.springframework.ldap.core.support.AbstractTlsDirContextAuthenticationStrategy;
+import org.springframework.ldap.core.support.DefaultTlsDirContextAuthenticationStrategy;
+import org.springframework.ldap.core.support.LdapContextSource;
+import org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy;
+import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+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;
+import org.springframework.security.ldap.userdetails.LdapUserDetails;
+
+/**
+ * Abstract LDAP based implementation of a login identity provider.
+ */
+public class LdapProvider implements LoginIdentityProvider {
+
+ private static final Logger logger = LoggerFactory.getLogger(LdapProvider.class);
+
+ private AbstractLdapAuthenticationProvider provider;
+ private String issuer;
+ private long expiration;
+
+ @Override
+ public final void initialize(final LoginIdentityProviderInitializationContext initializationContext) throws ProviderCreationException {
+ this.issuer = getClass().getSimpleName();
+ }
+
+ @Override
+ public final void onConfigured(final LoginIdentityProviderConfigurationContext configurationContext) throws ProviderCreationException {
+ final String rawExpiration = configurationContext.getProperty("Authentication Expiration");
+ if (StringUtils.isBlank(rawExpiration)) {
+ throw new ProviderCreationException("The Authentication Expiration must be specified.");
+ }
+
+ try {
+ expiration = FormatUtils.getTimeDuration(rawExpiration, TimeUnit.MILLISECONDS);
+ } catch (final IllegalArgumentException iae) {
+ throw new ProviderCreationException(String.format("The Expiration Duration '%s' is not a valid time duration", rawExpiration));
+ }
+
+ final LdapContextSource context = new LdapContextSource();
+
+ final Map<String, Object> baseEnvironment = new HashMap<>();
+
+ // connect/read time out
+ 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;
+ try {
+ authenticationStrategy = LdapAuthenticationStrategy.valueOf(rawAuthenticationStrategy);
+ } catch (final IllegalArgumentException iae) {
+ throw new ProviderCreationException(String.format("Unrecognized authentication strategy '%s'. Possible values are [%s]",
+ rawAuthenticationStrategy, StringUtils.join(LdapAuthenticationStrategy.values(), ", ")));
+ }
+
+ switch (authenticationStrategy) {
+ case ANONYMOUS:
+ context.setAnonymousReadOnly(true);
+ break;
+ default:
+ final String userDn = configurationContext.getProperty("Manager DN");
+ final String password = configurationContext.getProperty("Manager Password");
+
+ context.setUserDn(userDn);
+ context.setPassword(password);
+
+ switch (authenticationStrategy) {
+ case SIMPLE:
+ context.setAuthenticationStrategy(new SimpleDirContextAuthenticationStrategy());
+ break;
+ case START_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");
+ 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(), ", ")));
+ }
+ }
+
+ 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);
+ }
+
+ context.setAuthenticationStrategy(tlsAuthenticationStrategy);
+ break;
+ }
+ break;
+ }
+
+ // referrals
+ final String rawReferralStrategy = configurationContext.getProperty("Referral Strategy");
+
+ final ReferralStrategy referralStrategy;
+ try {
+ referralStrategy = ReferralStrategy.valueOf(rawReferralStrategy);
+ } catch (final IllegalArgumentException iae) {
+ throw new ProviderCreationException(String.format("Unrecgonized authentication strategy '%s'. Possible values are [%s]",
+ rawAuthenticationStrategy, StringUtils.join(ReferralStrategy.values(), ", ")));
+ }
+
+ context.setReferral(referralStrategy.toString());
+
+ // url
+ final String url = configurationContext.getProperty("Url");
+
+ if (StringUtils.isBlank(url)) {
+ throw new ProviderCreationException("LDAP identity provider 'Url' must be specified.");
+ }
+
+ // connection
+ context.setUrl(url);
+
+ // search criteria
+ 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.");
+ }
+
+ final LdapUserSearch userSearch = new FilterBasedLdapUserSearch(userSearchBase, userSearchFilter, context);
+
+ // bind
+ 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
+ provider = new LdapAuthenticationProvider(authenticator);
+ }
+
+ private void setTimeout(final LoginIdentityProviderConfigurationContext configurationContext,
+ final Map<String, Object> baseEnvironment,
+ final String configurationProperty,
+ final String environmentKey) {
+
+ final String rawTimeout = configurationContext.getProperty(configurationProperty);
+ if (StringUtils.isNotBlank(rawTimeout)) {
+ try {
+ final Long timeout = FormatUtils.getTimeDuration(rawTimeout, TimeUnit.MILLISECONDS);
+ baseEnvironment.put(environmentKey, timeout.toString());
+ } catch (final IllegalArgumentException iae) {
+ throw new ProviderCreationException(String.format("The %s '%s' is not a valid time duration", configurationProperty, rawTimeout));
+ }
+ }
+ }
+
+ @Override
+ public final AuthenticationResponse authenticate(final LoginCredentials credentials) throws InvalidLoginCredentialsException, IdentityAccessException {
+ if (provider == null) {
+ throw new IdentityAccessException("The LDAP authentication provider is not initialized.");
+ }
+
+ try {
+ // perform the authentication
+ final UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword());
+ final Authentication authentication = provider.authenticate(token);
+
+ // attempt to get the ldap user details to get the DN
+ if (authentication.getPrincipal() instanceof LdapUserDetails) {
+ final LdapUserDetails userDetails = (LdapUserDetails) authentication.getPrincipal();
+ return new AuthenticationResponse(userDetails.getDn(), credentials.getUsername(), expiration, issuer);
+ } else {
+ return new AuthenticationResponse(authentication.getName(), credentials.getUsername(), expiration, issuer);
+ }
+ } catch (final CommunicationException | AuthenticationServiceException e) {
+ logger.error(e.getMessage());
+ if (logger.isDebugEnabled()) {
+ logger.debug(StringUtils.EMPTY, e);
+ }
+ throw new IdentityAccessException("Unable to query the configured directory server. See the logs for additional details.", e);
+ } 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/aaf14c45/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/ReferralStrategy.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/ReferralStrategy.java b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/ReferralStrategy.java
new file mode 100644
index 0000000..f4c5131
--- /dev/null
+++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/ReferralStrategy.java
@@ -0,0 +1,39 @@
+/*
+ * 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 ReferralStrategy {
+
+ FOLLOW("follow"),
+ INGORE("ignore"),
+ THROW("throw");
+
+ private final String value;
+
+ private ReferralStrategy(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/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..b5ca1fe
--- /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,15 @@
+# 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
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/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/aaf14c45/nifi-nar-bundles/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/pom.xml b/nifi-nar-bundles/pom.xml
index 4c0925f..a9c7728 100644
--- a/nifi-nar-bundles/pom.xml
+++ b/nifi-nar-bundles/pom.xml
@@ -48,6 +48,7 @@
<module>nifi-avro-bundle</module>
<module>nifi-couchbase-bundle</module>
<module>nifi-azure-bundle</module>
+ <module>nifi-ldap-iaa-providers-bundle</module>
</modules>
<dependencyManagement>
<dependencies>
http://git-wip-us.apache.org/repos/asf/nifi/blob/aaf14c45/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 0708812..249f01c 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>3.2.7.RELEASE</spring.security.version>
+ <spring.security.version>4.0.3.RELEASE</spring.security.version>
<jersey.version>1.19</jersey.version>
<hadoop.version>2.6.2</hadoop.version>
<hadoop.guava.version>12.0.1</hadoop.guava.version>
@@ -290,8 +290,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>
@@ -361,7 +361,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>
@@ -504,6 +504,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>
@@ -977,6 +1000,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.4.0-SNAPSHOT</version>
</dependency>
@@ -1262,7 +1291,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>
@@ -1352,11 +1381,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>