Reputation: 1551
For working with IAM authentication for a DB, a dynamic password is required to refresh the connection pool with new credentials. in r2dbc-postgresql I could not find any possibility of a custom datasource like the one in HikariCP. Also there is no option to supply a dynamic password as concrete final class is used for config (PostgresConnectionConfiguration
)
Any hints for a workaround?
Upvotes: 2
Views: 911
Reputation: 721
I was just deep diving into this and trying to find a solution and I think I have it.
Although there is not any current support as mentioned by Anubis, you could definitely implement not a *ConnectionConfiguration, but a ConnectionFactory.
This approach should work for any need you have for rotating credentials, IAM Auth, rotating credentials via AWS Secrets Manager and any others. Also, I suppose it will work with any driver, as it is constructed with generic r2dbc-spi.
Below, a simple implementation for IAM Auth in Kotlin
fun interface ConnectionFactoryGenerator {
// user and pass just for generic usage
fun generate(username: String, password: String): ConnectionFactory
}
class RdsIamConnectionFactory(
private val client: RdsAsyncClient,
private val host: String,
private val port: Int,
private val username: String,
private val generator: ConnectionFactoryGenerator
) : ConnectionFactory {
// ugly, I know, but you need this to be the same metadata as underlying connection
private val metadata = generator.generate(username, "fake").metadata
override fun create(): Publisher<Connection> =
Mono.defer {
GenerateAuthenticationTokenRequest.builder()
.username(username)
.port(port)
.hostname(host)
.build()
.let(client.utilities()::generateAuthenticationToken)
.let { generator.generate(username, it) }
.create()
.let { Mono.from(it) }
}
override fun getMetadata(): ConnectionFactoryMetadata {
return metadata
}
}
You can use this like:
RdsIamConnectionFactory(
rdsAsyncClient,
databaseEnv.host,
databaseEnv.port,
databaseEnv.username,
) { _, pass ->
... setup your specific connection factory here ...
}
Now, this code is just good enough for me, but if you are worried that each connection is creating almost equal instances of ConnectionConfiguration / ConnectionFactory, you can always improve it with your own code on top of it.
In case you have any trouble testing this code, make sure you have:
Hope this helps, as I was trying to figure this out for a long time now and just decided to solve this.
Upvotes: 0