Implement verification_cooldown LDAP server connection param

This commit is contained in:
Denis Glazachev 2020-10-15 02:39:31 +04:00
parent 15d50d4581
commit f2a6696362
5 changed files with 61 additions and 1 deletions

View File

@ -222,6 +222,9 @@
auth_dn_prefix, auth_dn_suffix - prefix and suffix used to construct the DN to bind to.
Effectively, the resulting DN will be constructed as auth_dn_prefix + escape(user_name) + auth_dn_suffix string.
Note, that this implies that auth_dn_suffix should usually have comma ',' as its first non-space character.
verification_cooldown - a period of time, in seconds, after a successful bind attempt, during which a user will be assumed
to be successfully authenticated for all consecutive requests without contacting the LDAP server.
Specify 0 (the default) to disable caching and force contacting the LDAP server for each authentication request.
enable_tls - flag to trigger use of secure connection to the LDAP server.
Specify 'no' for plain text (ldap://) protocol (not recommended).
Specify 'yes' for LDAP over SSL/TLS (ldaps://) protocol (recommended, the default).
@ -241,6 +244,7 @@
<port>636</port>
<auth_dn_prefix>uid=</auth_dn_prefix>
<auth_dn_suffix>,ou=users,dc=example,dc=com</auth_dn_suffix>
<verification_cooldown>300</verification_cooldown>
<enable_tls>yes</enable_tls>
<tls_minimum_protocol_version>tls1.2</tls_minimum_protocol_version>
<tls_require_cert>demand</tls_require_cert>

View File

@ -86,8 +86,37 @@ bool Authentication::isCorrectPassword(const String & password_, const String &
ldap_server_params.user = user_;
ldap_server_params.password = password_;
const auto current_params_hash = ldap_server_params.getCoreHash();
const auto last_check_period = std::chrono::steady_clock::now() - last_successful_password_check_timestamp;
if (
// Forbid the initial values explicitly.
last_successful_password_check_params_hash != 0 &&
last_successful_password_check_timestamp != std::chrono::steady_clock::time_point{} &&
// Check if we can "reuse" the result of the previous successful password verification.
current_params_hash == last_successful_password_check_params_hash &&
last_check_period <= ldap_server_params.verification_cooldown
)
{
return true;
}
LDAPSimpleAuthClient ldap_client(ldap_server_params);
return ldap_client.check();
const auto result = ldap_client.check();
if (result)
{
last_successful_password_check_params_hash = current_params_hash;
last_successful_password_check_timestamp = std::chrono::steady_clock::now();
}
else
{
last_successful_password_check_params_hash = 0;
last_successful_password_check_timestamp = std::chrono::steady_clock::time_point{};
}
return result;
}
case MAX_TYPE:

View File

@ -6,6 +6,7 @@
#include <Poco/SHA1Engine.h>
#include <boost/algorithm/hex.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <chrono>
namespace DB
@ -103,7 +104,11 @@ private:
Type type = Type::NO_PASSWORD;
Digest password_hash;
// Used and maintained only for LDAP.
String server_name;
mutable std::size_t last_successful_password_check_params_hash = 0;
mutable std::chrono::steady_clock::time_point last_successful_password_check_timestamp;
};

View File

@ -29,6 +29,7 @@ auto parseLDAPServer(const Poco::Util::AbstractConfiguration & config, const Str
const bool has_port = config.has(ldap_server_config + ".port");
const bool has_auth_dn_prefix = config.has(ldap_server_config + ".auth_dn_prefix");
const bool has_auth_dn_suffix = config.has(ldap_server_config + ".auth_dn_suffix");
const bool has_verification_cooldown = config.has(ldap_server_config + ".verification_cooldown");
const bool has_enable_tls = config.has(ldap_server_config + ".enable_tls");
const bool has_tls_minimum_protocol_version = config.has(ldap_server_config + ".tls_minimum_protocol_version");
const bool has_tls_require_cert = config.has(ldap_server_config + ".tls_require_cert");
@ -52,6 +53,9 @@ auto parseLDAPServer(const Poco::Util::AbstractConfiguration & config, const Str
if (has_auth_dn_suffix)
params.auth_dn_suffix = config.getString(ldap_server_config + ".auth_dn_suffix");
if (has_verification_cooldown)
params.verification_cooldown = std::chrono::seconds{config.getUInt64(ldap_server_config + ".verification_cooldown")};
if (has_enable_tls)
{
String enable_tls_lc_str = config.getString(ldap_server_config + ".enable_tls");

View File

@ -2,6 +2,8 @@
#include <common/types.h>
#include <boost/container_hash/hash.hpp>
#include <chrono>
@ -68,10 +70,26 @@ struct LDAPServerParams
String user;
String password;
std::chrono::seconds verification_cooldown{0};
std::chrono::seconds operation_timeout{40};
std::chrono::seconds network_timeout{30};
std::chrono::seconds search_timeout{20};
std::uint32_t search_limit = 100;
std::size_t getCoreHash() const
{
std::size_t seed = 0;
boost::hash_combine(seed, host);
boost::hash_combine(seed, port);
boost::hash_combine(seed, auth_dn_prefix);
boost::hash_combine(seed, auth_dn_suffix);
boost::hash_combine(seed, user);
boost::hash_combine(seed, password);
return seed;
}
};
}