使用Java连接池进行AWS IAM数据库身份验证
我正在寻找一个Java数据库连接池,它允许我对我的Aurora MySQL使用AWS IAM数据库身份验证。该池应该能够使用Tomcat context.xml文件 我已经研究了Tomcat DBCP、dbcp2、HikariCP和c3p0。但它们似乎都表明用户名和密码在应用程序启动时是已知的,并且在应用程序的生命周期中不会更改 对于IAM数据库身份验证,凭据每15分钟更改一次,因此池需要在创建新连接时向AWS IAM请求新凭据(凭据可以缓存几分钟)使用Java连接池进行AWS IAM数据库身份验证,java,amazon-web-services,amazon-rds,amazon-iam,Java,Amazon Web Services,Amazon Rds,Amazon Iam,我正在寻找一个Java数据库连接池,它允许我对我的Aurora MySQL使用AWS IAM数据库身份验证。该池应该能够使用Tomcat context.xml文件 我已经研究了Tomcat DBCP、dbcp2、HikariCP和c3p0。但它们似乎都表明用户名和密码在应用程序启动时是已知的,并且在应用程序的生命周期中不会更改 对于IAM数据库身份验证,凭据每15分钟更改一次,因此池需要在创建新连接时向AWS IAM请求新凭据(凭据可以缓存几分钟) 这是在任何Java连接池中实现的吗?或者你有
这是在任何Java连接池中实现的吗?或者你有没有办法让它工作起来?我最近也遇到了同样的问题。。。。我使用HikariCP连接池,到目前为止,它还不支持此功能。幸运的是,我用这个工具找到了一个PR: 我建议您制作一个项目fork并在官方存储库接受此PR之前使用它 我对这一点的执行:
public DataSource setup() throws Exception {
Supplier<String> passwordSupplier = () -> {
return this.generateAuthToken(host, port, user);
};
com.zaxxer.hikari.HikariDataSource dataSource = new com.zaxxer.hikari.HikariDataSource();
dataSource.setPasswordSupplier(passwordSupplier); ...
因为您的池连接不能使用RDS Iam Auth超过15分钟
祝你好运。我也不得不使用节点js lambda和MySql RDS来面对这个问题。我们使用了一个连接池,因此我们实现了一个解决方案,该解决方案创建了一个未来的日期时间,我们可以检查连接是否即将到期,无论何时从连接池请求连接。这个日期时间是15分钟减去连接池初始化后的一些抖动 因此,获取连接池(以获取连接)的过程如下所示:
const getPool = async (): Promise<DbConnectionPool> => {
if (isRdsIamTokenCloseToExpiring()) {
await poolHolder.lock.acquire();
try {
// if, after having acquired lock, thread pool is still about to expire...
if (isRdsIamTokenCloseToExpiring()) {
await closeConnectionsInPool();
await initializeConnectionPool();
}
} finally {
poolHolder.lock.release();
}
}
if (!poolHolder.pool) {
throw new Error('pool holder is null - this should never happen');
} else {
return poolHolder.pool;
}
};
const getPool=async():Promise=>{
if(isRdsIamTokenCloseToExpiring()){
等待poolHolder.lock.acquire();
试一试{
//若在获得锁后,线程池仍将过期。。。
如果(isRdsIamTokenCloseToExpiring()){
等待关闭连接输入工具();
等待初始化连接池();
}
}最后{
poolHolder.lock.release();
}
}
如果(!poolHolder.pool){
抛出新错误('pool holder为null-这永远不会发生');
}否则{
返回poolHolder.pool;
}
};
因为我们有多个并发异步线程试图获得连接,所以我们必须引入一个信号量来控制池的重新初始化。总而言之,这样做比使用用户名和密码更麻烦,但更安全
要回答Isen Ng的上述评论(我没有代表直接回答),RDS IAM令牌过期的连接将停止工作 我知道这是一个较老的问题,但经过一番搜索后,我找到了一种非常简单的方法,现在可以使用MariaDB驱动程序来实现这一点。在版本2.5中,他们在驱动程序中添加了一个。它将自动处理令牌的生成、缓存和刷新。您可以这样激活它:
jdbc:mariadb://host/db?credentialType=AWS-IAM&useSsl&serverSslCert=/somepath/rds组合ca bundle.pem
我已经使用HikariCP连接池进行了测试,它对我很有效。确保您使用的是MariaDB驱动程序(不是MySQL),并将maxLifetime
设置为600000ms(驱动程序缓存令牌10分钟)
希望这对其他人有所帮助-我在网上找到的大多数示例都涉及自定义代码、后台线程等-但是使用新的驱动程序功能要容易得多 有一个很酷的方法。请参阅您确定
dataSource.setMaxLifetime(15*60*1000)代码>是必需的吗?我一直认为,一旦物理连接打开,密码是否更改/令牌是否无效并不重要。新连接将需要新密码/有效令牌,但现有连接将继续工作。当我有时间的时候,我将在本周测试这个假设。
const getPool = async (): Promise<DbConnectionPool> => {
if (isRdsIamTokenCloseToExpiring()) {
await poolHolder.lock.acquire();
try {
// if, after having acquired lock, thread pool is still about to expire...
if (isRdsIamTokenCloseToExpiring()) {
await closeConnectionsInPool();
await initializeConnectionPool();
}
} finally {
poolHolder.lock.release();
}
}
if (!poolHolder.pool) {
throw new Error('pool holder is null - this should never happen');
} else {
return poolHolder.pool;
}
};