检测传递给 c3p0 连接池的无效凭据

Detect invalid credentials being passed to c3p0 connection pool

我正在编写一个程序来对数据库执行一些操作。允许用户通过传递数据库主机端口、类型和凭据来配置数据库进程。当值正确时,一切正常。但是当用户传递无效凭据时,我想显示一个错误。所以这是我创建连接池的部分

ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setJdbcUrl( connectionUrl );
cpds.setUser(username);
cpds.setPassword(password);

然后验证我的连接是否一切正常

cpds.getConnection()

我希望得到一些 SQLException 与供应商特定的错误,表明凭据无效(当您使用典型的 DriverManager 方式获取连接时会发生这种情况),但进程会等待直到抛出连接检查异常

java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:118)
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:77)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:690)
....
Caused by: com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResourcePool@20014b8 -- timeout at awaitAvailable()
    at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1467)
    at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:644)
    at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:554)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:758)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:685)
    ... 66 more

如何确定 c3p0 存在无效凭据问题?

JDBC 提供商可以自由创建他们想要的任何 error/exception 消息。因此,您需要准备好解析每个提供程序的错误消息,以便了解正在发生的事情。

您还可以尝试从异常类型中获取信息如果 JDBC 提供程序将错误隔离在不同的类型中。

附带说明一下,提供过多有关连接失败原因的信息可能会被视为安全漏洞。因此,不应期望 JDBC 驱动程序会为您提供此类信息。例如,为什么任何数据库都会通过说 "the username is correct, but the password is not."?

来配合入侵企图

验证提供的 credentials/JDBC 参数的最佳方法是完全避免使用连接池。

为此目的打开专用连接并尝试对新连接(例如SELECT 1 或类似)执行最简单的SQL。 成功后,您可以将它们传递给 C3P0,否则将错误传播回用户。