From cfee612a78e4256fc0295e6ad1315ba26996ed94 Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Wed, 11 Nov 2015 19:40:40 -0500 Subject: [PATCH] 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. --- 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 +++++++ .../nifi/ldap/AbstractLdapProvider.java | 80 ++++++++++ .../nifi/ldap/ActiveDirectoryProvider.java | 46 ++++++ .../nifi/ldap/LdapAuthenticationStrategy.java | 27 ++++ .../org/apache/nifi/ldap/LdapProvider.java | 151 ++++++++++++++++++ ....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(-) create mode 100644 nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml create mode 100644 nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml create mode 100644 nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/AbstractLdapProvider.java create mode 100644 nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/ActiveDirectoryProvider.java create mode 100644 nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapAuthenticationStrategy.java create mode 100644 nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/LdapProvider.java create mode 100644 nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/resources/META-INF/services/org.apache.nifi.authentication.LoginIdentityProvider create mode 100644 nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml diff --git a/nifi-assembly/pom.xml b/nifi-assembly/pom.xml index 254dff0a5f..db0a083ecd 100644 --- a/nifi-assembly/pom.xml +++ b/nifi-assembly/pom.xml @@ -172,6 +172,11 @@ language governing permissions and limitations under the License. --> nifi-flume-nar nar + + org.apache.nifi + nifi-ldap-iaa-providers-nar + nar + org.apache.nifi nifi-dbcp-service-nar 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 1e68d168c6..5c3b3e6954 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(); 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 c316ef28dd..894ade84fa 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); 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 12f7ed71f6..f844d91d30 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(); }; @@ -329,6 +329,29 @@ nf.Login = (function () { logout(); } + // no token granted, user needs to login with their credentials + needsLogin = true; + }).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 () { 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 0000000000..59681b93c8 --- /dev/null +++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers-nar/pom.xml @@ -0,0 +1,32 @@ + + + + 4.0.0 + + org.apache.nifi + nifi-ldap-iaa-providers-bundle + 0.3.1-SNAPSHOT + + nifi-ldap-iaa-providers-nar + nar + + + org.apache.nifi + nifi-ldap-iaa-providers + + + nifi-ldap-iaa-providers-nar + \ No newline at end of file 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 0000000000..9f5b5e8883 --- /dev/null +++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/pom.xml @@ -0,0 +1,56 @@ + + + + 4.0.0 + + org.apache.nifi + nifi-ldap-iaa-providers-bundle + 0.3.1-SNAPSHOT + + nifi-ldap-iaa-providers + jar + + + org.apache.nifi + nifi-api + + + org.apache.nifi + nifi-security-utils + + + org.springframework.security + spring-security-ldap + + + org.springframework + spring-beans + + + org.springframework + spring-context + + + org.springframework + spring-tx + + + org.apache.commons + commons-lang3 + + + nifi-ldap-iaa-providers + \ No newline at end of file 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 0000000000..c7f338b2d2 --- /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 { + } + +} 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 0000000000..7be8ec9673 --- /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); + } +} 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 0000000000..a3c4f0973b --- /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 +} 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 0000000000..7d471d551f --- /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); + } +} 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 0000000000..2158cf7bdb --- /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 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 0000000000..e038c2cb51 --- /dev/null +++ b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/pom.xml @@ -0,0 +1,38 @@ + + + + 4.0.0 + + org.apache.nifi + nifi-nar-bundles + 0.3.1-SNAPSHOT + + nifi-ldap-iaa-providers-bundle + pom + + nifi-ldap-iaa-providers + nifi-ldap-iaa-providers-nar + + + + + org.apache.nifi + nifi-ldap-iaa-providers + 0.3.1-SNAPSHOT + + + + \ No newline at end of file diff --git a/nifi-nar-bundles/pom.xml b/nifi-nar-bundles/pom.xml index 841818aeaf..8592b08c50 100644 --- a/nifi-nar-bundles/pom.xml +++ b/nifi-nar-bundles/pom.xml @@ -46,6 +46,7 @@ nifi-image-bundle nifi-avro-bundle nifi-couchbase-bundle + nifi-ldap-iaa-providers-bundle diff --git a/pom.xml b/pom.xml index ffb21a8f33..667ed630b2 100644 --- a/pom.xml +++ b/pom.xml @@ -1,14 +1,14 @@ +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. --> 4.0.0 @@ -91,7 +91,7 @@ 9.2.11.v20150529 4.10.4 4.1.6.RELEASE - 4.0.2.RELEASE + 4.0.3.RELEASE 1.19 2.6.0 2.2.0 @@ -251,8 +251,8 @@ 2.2.1 + lgpl licensed | We also don't use the JDBC related features of quartz for + which the dependency would matter --> c3p0 c3p0 @@ -322,7 +322,7 @@ ${spring.version} + section --> commons-logging commons-logging @@ -464,6 +464,29 @@ + + org.springframework.security + spring-security-ldap + ${spring.security.version} + + + org.springframework + spring-core + + + org.springframework + spring-beans + + + org.springframework + spring-context + + + org.springframework + spring-tx + + + org.aspectj aspectjweaver @@ -912,6 +935,12 @@ 0.3.1-SNAPSHOT nar + + org.apache.nifi + nifi-ldap-iaa-providers-nar + 0.3.1-SNAPSHOT + nar + org.apache.nifi nifi-properties @@ -1189,7 +1218,7 @@ + brace --> @@ -1279,11 +1308,11 @@ + 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. --> contrib-check