能否通过AWS SDK Ruby v3自动刷新AWS SSO令牌,替代手动执行aws sso login
使用AWS SDK Ruby v3原生实现SSO登录流程
AWS SDK Ruby v3没有直接封装aws sso login的完整命令,但可以利用SDK底层的SSO OIDC客户端实现核心流程,无需调用CLI。以下是具体实现步骤:
核心实现步骤
1. 加载目标SSO配置文件
通过Aws::SharedConfig读取本地AWS配置中的SSO会话信息:
require 'aws-sdk-core' require 'json' require 'fileutils' require 'digest' # 替换为你的SSO配置文件名称 profile_name = 'your-sso-profile' # 加载SSO配置 shared_config = Aws::SharedConfig.new(profile: profile_name) sso_session = shared_config.sso_session_config sso_region = sso_session['sso_region'] sso_start_url = sso_session['sso_start_url']
2. 初始化SSO OIDC客户端
创建处理OIDC授权流程的客户端:
sso_oidc_client = Aws::SSOOIDC::Client.new(region: sso_region)
3. 注册应用客户端
在AWS SSO中注册当前应用,获取客户端凭证:
register_response = sso_oidc_client.register_client({ client_name: 'Ruby App SSO Client', client_type: 'public' }) client_id = register_response.client_id client_secret = register_response.client_secret
4. 启动设备授权流程
生成用户登录所需的URL和验证代码,提示用户完成浏览器登录:
authorize_response = sso_oidc_client.start_device_authorization({ client_id: client_id, client_secret: client_secret, start_url: sso_start_url }) # 输出登录提示 puts "请打开以下链接完成登录:#{authorize_response.verification_uri_complete}" puts "或访问 #{authorize_response.verification_uri} 并输入验证码:#{authorize_response.user_code}"
5. 轮询获取访问令牌
等待用户完成登录后,轮询获取令牌并写入AWS SSO缓存目录(与CLI共享缓存):
# 处理轮询逻辑,捕获授权中状态并重试 begin token_response = sso_oidc_client.create_token({ client_id: client_id, client_secret: client_secret, device_code: authorize_response.device_code, grant_type: 'urn:ietf:params:oauth:grant-type:device_code' }) rescue Aws::SSOOIDC::Errors::AuthorizationPendingException sleep(authorize_response.interval) retry end # 构建符合CLI格式的缓存数据 cache_data = { "clientId" => client_id, "clientSecret" => client_secret, "expiresAt" => (Time.now + token_response.expires_in).iso8601, "refreshToken" => token_response.refresh_token, "startUrl" => sso_start_url, "region" => sso_region } # 写入SSO缓存文件 cache_dir = File.join(Dir.home, '.aws', 'sso', 'cache') FileUtils.mkdir_p(cache_dir) cache_file = File.join(cache_dir, "#{Digest::SHA256.hexdigest(sso_start_url)}.json") File.write(cache_file, JSON.pretty_generate(cache_data))
6. 令牌自动刷新(可选)
当令牌过期时,可使用刷新令牌重新获取有效令牌:
# 从缓存读取刷新令牌 cached_data = JSON.parse(File.read(cache_file)) refresh_response = sso_oidc_client.create_token({ client_id: cached_data['clientId'], client_secret: cached_data['clientSecret'], refresh_token: cached_data['refreshToken'], grant_type: 'refresh_token' }) # 更新缓存 cached_data['expiresAt'] = (Time.now + refresh_response.expires_in).iso8601 cached_data['refreshToken'] = refresh_response.refresh_token File.write(cache_file, JSON.pretty_generate(cached_data))
注意事项
- 缓存路径与AWS CLI完全一致,确保SDK后续能自动读取凭证
- 需处理
AuthorizationPendingException(用户未完成登录)、ExpiredTokenException(设备码过期)等异常 - 确保应用有读取
~/.aws/config和写入~/.aws/sso/cache的权限
内容的提问来源于stack exchange,提问作者Guss
相关产品推荐
相关产品推荐

