NIFI-655:

- Adding configuration options for referrals and connect/read timeouts
This commit is contained in:
Matt Gilman 2015-11-16 21:16:23 -05:00
parent c659485ee4
commit 9ccf61aff1
3 changed files with 111 additions and 12 deletions

View File

@ -30,11 +30,13 @@ import org.apache.nifi.authorization.exception.ProviderDestructionException;
import org.apache.nifi.util.FormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.CommunicationException;
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.userdetails.LdapUserDetails;
/**
* Abstract LDAP based implementation of a login identity provider.
@ -59,7 +61,7 @@ public abstract class AbstractLdapProvider implements LoginIdentityProvider {
try {
expiration = FormatUtils.getTimeDuration(rawExpiration, TimeUnit.MILLISECONDS);
} catch (final NumberFormatException nfe) {
} catch (final IllegalArgumentException iae) {
throw new ProviderCreationException(String.format("The Expiration Duration '%s' is not a valid time duration", rawExpiration));
}
@ -75,15 +77,23 @@ public abstract class AbstractLdapProvider implements LoginIdentityProvider {
}
try {
// perform the authentication
final UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword());
final Authentication authentication = provider.authenticate(token);
return new AuthenticationResponse(authentication.getPrincipal().toString(), credentials.getUsername());
} catch (final AuthenticationServiceException ase) {
logger.error(ase.getMessage());
if (logger.isDebugEnabled()) {
logger.debug(StringUtils.EMPTY, ase);
// 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());
} else {
return new AuthenticationResponse(authentication.getName(), credentials.getUsername());
}
throw new IdentityAccessException("Unable to query the configured directory server. See the logs for additional details.", ase);
} 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);
}

View File

@ -22,12 +22,16 @@ 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.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.apache.nifi.util.FormatUtils;
import org.springframework.ldap.core.support.AbstractTlsDirContextAuthenticationStrategy;
import org.springframework.ldap.core.support.DefaultTlsDirContextAuthenticationStrategy;
import org.springframework.ldap.core.support.DigestMd5DirContextAuthenticationStrategy;
@ -50,12 +54,43 @@ public class LdapProvider extends AbstractLdapProvider {
protected AbstractLdapAuthenticationProvider getLdapAuthenticationProvider(LoginIdentityProviderConfigurationContext configurationContext) throws ProviderCreationException {
final LdapContextSource context = new LdapContextSource();
final Map<String, Object> baseEnvironment = new HashMap<>();
// connection time out
final String rawConnectTimeout = configurationContext.getProperty("Connect Timeout");
if (StringUtils.isNotBlank(rawConnectTimeout)) {
try {
final Long connectTimeout = FormatUtils.getTimeDuration(rawConnectTimeout, TimeUnit.MILLISECONDS);
baseEnvironment.put("com.sun.jndi.ldap.connect.timeout", connectTimeout.toString());
} catch (final IllegalArgumentException iae) {
throw new ProviderCreationException(String.format("The Connect Timeout '%s' is not a valid time duration", rawConnectTimeout));
}
}
// read time out
final String rawReadTimeout = configurationContext.getProperty("Read Timeout");
if (StringUtils.isNotBlank(rawReadTimeout)) {
try {
final Long readTimeout = FormatUtils.getTimeDuration(rawReadTimeout, TimeUnit.MILLISECONDS);
baseEnvironment.put("com.sun.jndi.ldap.read.timeout", readTimeout.toString());
} catch (final IllegalArgumentException iae) {
throw new ProviderCreationException(String.format("The Read Timeout '%s' is not a valid time duration", rawReadTimeout));
}
}
// 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("Unrecgonized authentication strategy '%s'", rawAuthenticationStrategy));
throw new ProviderCreationException(String.format("Unrecgonized authentication strategy '%s'. Possible values are [%s]",
rawAuthenticationStrategy, StringUtils.join(LdapAuthenticationStrategy.values(), ", ")));
}
switch (authenticationStrategy) {
@ -63,8 +98,8 @@ public class LdapProvider extends AbstractLdapProvider {
context.setAnonymousReadOnly(true);
break;
default:
final String userDn = configurationContext.getProperty("Bind DN");
final String password = configurationContext.getProperty("Bind Password");
final String userDn = configurationContext.getProperty("Manager DN");
final String password = configurationContext.getProperty("Manager Password");
context.setUserDn(userDn);
context.setPassword(password);
@ -122,6 +157,20 @@ public class LdapProvider extends AbstractLdapProvider {
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)) {
@ -131,6 +180,7 @@ public class LdapProvider extends AbstractLdapProvider {
// connection
context.setUrl(url);
// search criteria
final String userSearchBase = configurationContext.getProperty("User Search Base");
final String userSearchFilter = configurationContext.getProperty("User Search Filter");
@ -138,7 +188,6 @@ public class LdapProvider extends AbstractLdapProvider {
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
@ -154,6 +203,7 @@ public class LdapProvider extends AbstractLdapProvider {
}
// create the underlying provider
return new LdapAuthenticationProvider(authenticator);
final LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(authenticator);
return ldapAuthenticationProvider;
}
}

View File

@ -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;
}
}