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>
