AWS IAM Database Authentication using Java connection pool

大兔子大兔子 提交于 2021-01-03 06:44:31

问题


I am looking for a Java database connection pool that allows me to use AWS IAM Database Authentication for my Aurora MySQL. The pool should be able to work Tomcat context.xml file.

I have looked at Tomcat DBCP, dbcp2, HikariCP and c3p0. But they all seem to asume the username and password is known at application startup and does not change in the lifetime of the application.

For IAM database authentication the credentials change every 15 minutes so the pool needs to ask the AWS IAM for a new credentials whenever it creates new connections (the credentials could be cached a few minutes.).

Is this implemented in any Java connection pool? Or do you have an idea on how get this to work?


回答1:


I've also had to face this problem using node js lambda and MySql RDS. We were using a mysql connection pool and so we implemented a solution that created a future date-time that we could check to see if connections were about to expire whenever a connection was requested from the pool. This date-time was 15 minutes minus some jitter after the connection pool was initialized.

So getting the connection pool (to get a connection) would look like:

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

Because we had multiple concurrent async threads trying to get a connection we had to introduce a semaphore to control the pool re-initialization. All in all having to do this was more cumbersome than using a username & password but it is more secure.

To answer Isen Ng's comment above (I don't have the rep to answer directly), connections whose RDS IAM token expires will stop working.




回答2:


I had the same problem recently.... I use HikariCP connection pool and until now it does not have support for this. Fortunately I found a PR with this tool:

https://github.com/brettwooldridge/HikariCP/pull/1335

I recommend you make a project fork and use it until the official repository accepts this PR.

My implementation of this:

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); ...

It's very important include this on your pool configuration:

dataSource.setMaxLifetime(15 * 60 * 1000); 

Because your pool connections can't live more than 15 minutes with RDS Iam Auth

Good luck.




回答3:


I know this is an older question, but after a some searching I found a pretty easy way you can now do this using the MariaDB driver. In version 2.5 they added an AWS IAM credential plugin to the driver. It will handle generating, caching and refreshing the token automatically. You can activate it like this:

jdbc:mariadb://host/db?credentialType=AWS-IAM&useSsl&serverSslCert=/somepath/rds-combined-ca-bundle.pem

I've tested using HikariCP connection pool and it is working for me. Make sure you are using the MariaDB driver (not MySQL) and set maxLifetime to 600000ms (driver caches tokens for 10 minutes).

Hope this helps someone else - most examples I found online involved custom code, background threads, etc - but using the new driver feature is much easier!



来源:https://stackoverflow.com/questions/50235147/aws-iam-database-authentication-using-java-connection-pool

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!