gpt4 book ai didi

ruby-on-rails - AWS RDS - 使用 Rails 进行 IAM 数据库身份验证

转载 作者:行者123 更新时间:2023-12-04 03:41:53 26 4
gpt4 key购买 nike

我希望使用 AWS RDS IAM database authentication使用 Ruby on Rails,因为它为 AWS 用户提供了一种方便的方式来管理数据库权限并避免将数据库密码存储在他们的代码库中。

在较高级别上,它的工作原理是根据您的 AWS 凭证生成密码以连接到仅 15 分钟有效的数据库。如果您想在 15 分钟后再次连接,则需要生成一个新密码。

该密码可以使用 AWS Ruby SDK 轻松生成,因此理论上可以嵌入 config/database.yml像这样;

production:
adapter: mysql2
host: db_host
database: db_name
username: db_user
password: <%=
Aws::RDS::AuthTokenGenerator
.new(credentials: Aws::InstanceProfileCredentials.new)
.auth_token(
region: 'us-east-1',
endpoint: 'db_host:3306',
user_name: 'db_user'
)
%>

但是,据我所知, config/database.yml仅在启动时评估一次,并在 Rails 的生命周期内保持缓存在该状态。

因此,通过使用这种方法,Rails 服务器最初会成功连接到数据库,但是如果在第一个 15 分钟窗口后的任何时候 Rails 尝试打开新的数据库连接或重新连接断开的连接,现在过期的凭据将是拒绝了。

使用 Rails 进行 IAM 数据库身份验证的最佳方法是什么?我是否需要以某种方式使用在每次连接建立时重新评估的密码的数据库配置?

最佳答案

我想了一些解决这个问题的方法,我想出的最好方法是monkeypatching Mysql2::Client#initialize以便您可以启用 IAM 数据库身份验证,它会将密码属性透明地更改为 RDS 密码。这似乎适用于 Rails 5.2.2.1 和 mysql 0.5.2.

一个关键的警告是您不能启用客户端的重新连接功能,因为我们需要确保 Rails 在发生连接错误时回收客户端(这似乎在上述 Rails 版本中默认发生)。

# config/database.rb
require 'aws-sdk-rds'
require 'mysql2'

Aws.config.update(
region: 'your_region',
)

class RdsIamPasswordGenerator
def self.generate(region, host, user, port)
Aws::RDS::AuthTokenGenerator
.new(credentials: Aws::InstanceProfileCredentials.new)
.auth_token(
region: region,
endpoint: host.to_s + ':' + port.to_s,
user_name: user
)
end
end

module MysqlClientIamMonkeyPatch
def initialize(opts = {})
opts = opts.dup
aws_iam_auth = opts.delete(:aws_iam_auth)

if aws_iam_auth
raise ArgumentError, 'reconnect must be false if aws_iam_auth is true' if opts[:reconnect]

user = opts[:username] || opts[:user]
host = opts[:host] || opts[:hostname]
port = opts[:port] || 3306

raise ArgumentError, 'username/user and host/hostname must be present' if user.nil? || host.nil?

opts.delete(:pass)
opts.delete(:password)

opts[:password] = RdsIamPasswordGenerator.generate(Aws.config[:region], host, user, port)
opts[:enable_cleartext_plugin] = true # Necessary for IAM auth
end

super(opts)
end
end

Mysql2::Client.prepend(MysqlClientIamMonkeyPatch)
# config/boot.rb
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)

require 'bundler/setup' # Set up gems listed in the Gemfile.
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.

require_relative './database' # Handles patching in IAM auth
# config/database.yml
production:
adapter: mysql2
database: production
ssl_mode: verify_identity
sslverify: true
sslca: /opt/aws/rds-combined-ca-bundle.pem
aws_iam_auth: true
host: db_host
username: db_user
password: null

关于ruby-on-rails - AWS RDS - 使用 Rails 进行 IAM 数据库身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47502253/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com