Boto3的IAM身份验证的SQLAlchemy可刷新凭据

时间:2020-04-08 12:41:56

标签: python-3.x sqlalchemy boto3 amazon-rds

我正在使用Boto3生成的身份验证令牌通过Sqlalchemy连接到Amazon RDS:

self.client = boto3.client("rds", region_name="eu-central-1")
self.token = self.client.generate_db_auth_token(
   self.endpoint, self.port, self.user
)

connection_string = (
   f"postgresql://{urlquote(self.user)}:"
   f"{urlquote(self.token)}@{self.endpoint}:{self.port}/dummy"
)

self.engine = db.create_engine(connection_string)

问题在于所提供的令牌仅在15分钟内有效(我想使用临时凭证!),现在我不知道如何在旧的令牌过期时告诉SQLAlchemy自动创建新的身份验证令牌。 / p>

我找到了creator参数,但是当令牌无效时,似乎没有调用此函数:

def get_new_connection(self):
    self.token = self.client.generate_db_auth_token(
        self.endpoint, self.port, self.user
    )
    conn = psycopg2.connect(
        f"dbname='dummy' user='{self.user}' host='{self.endpoint}' password='{self.token}'"
    )
    return conn


 self.engine = db.create_engine(
 connection_string, creator=self.get_new_connection
 )

是否有内置功能,或者有更优雅的解决方法?

1 个答案:

答案 0 :(得分:0)

根据SQLAlchemy documentation,使用易失性身份验证凭据的“正确”方式是利用事件系统:

<块引用>

生成动态身份验证令牌

DialectEvents.do_connect() 也是动态插入的理想方式 可能会在整个生命周期内发生变化的身份验证令牌 引擎。例如,如果令牌是由 get_authentication_token() 并在令牌中传递给 DBAPI 参数,这可以实现为:

from sqlalchemy import event

engine = create_engine("postgresql://user@hostname/dbname")

@event.listens_for(engine, "do_connect")
def provide_token(dialect, conn_rec, cargs, cparams):
    cparams['token'] = get_authentication_token()

尽管有多种方式可以使用 SQLAlchemy 事件系统,但我强烈建议您首先阅读 documentation on how to work with events 并根据您的特定需求选择正确的实现/机制。

根据这些信息,我能够在引擎需要建立新连接时生成新的 RDS IAM 密码。