使用Boto3调用STS get_caller_identity时无法捕获SSO凭证过期异常
Boto3 SSO凭证过期异常无法捕获的解决技巧
在使用Boto3 v1.26.59(配套同版本botocore)获取Identity Center(SSO)用户用户名时,凭证过期调用sts.get_caller_identity()会抛出UnauthorizedException和UnauthorizedSSOTokenError,但现有代码无法直接捕获这两个异常,最终被通用Exception捕获。以下是几个可行的解决技巧:
1. 提前触发凭证刷新,主动捕获异常
SSO凭证的刷新逻辑默认在首次调用AWS接口时触发,异常可能被botocore内部逻辑包装。可以在创建STS客户端前,主动获取并刷新凭证,让异常在可控阶段抛出:
import boto3 import botocore.exceptions as bcexp from typing import Optional def profile_user_name(profile_name: str) -> Optional[str]: session = boto3.Session(profile_name=profile_name) try: # 主动获取并刷新凭证,触发SSO校验 credentials = session.get_credentials() if credentials: credentials.refresh() else: raise bcexp.UnauthorizedSSOTokenError() sts = session.client("sts") user_id = sts.get_caller_identity().get("UserId") return user_id.split(":")[-1].split("@")[0] except bcexp.UnauthorizedSSOTokenError as e: _logger.error(f'Not authenticated. Please execute: aws sso login --profile {profile_name}') return None except Exception as e: _logger.error(f"Encountered exception '{str(e)}'!") return None
2. 捕获ClientError并校验错误码
botocore.errorfactory.UnauthorizedException是服务动态生成的异常,直接捕获可能失效。改用捕获botocore.exceptions.ClientError,通过错误码判断异常类型:
import boto3 import botocore.exceptions as bcexp from typing import Optional def profile_user_name(profile_name: str) -> Optional[str]: session = boto3.Session(profile_name=profile_name) sts = session.client("sts") try: user_id = sts.get_caller_identity().get("UserId") return user_id.split(":")[-1].split("@")[0] except bcexp.UnauthorizedSSOTokenError as e: _logger.error(f'Not authenticated. Please execute: aws sso login --profile {profile_name}') return None except bcexp.ClientError as e: error_code = e.response.get('Error', {}).get('Code') if error_code in ('UnauthorizedException', 'InvalidToken'): _logger.error(f'Not authenticated. Please execute: aws sso login --profile {profile_name}') return None _logger.error(f"Encountered client exception '{str(e)}'!") return None except Exception as e: _logger.error(f"Encountered exception '{str(e)}'!") return None
3. 验证实际异常类型
如果仍无法捕获,可在通用Exception块中打印异常类型,确认抛出的异常是否与你捕获的类一致,排查导入或类路径问题:
except Exception as e: # 打印异常类型用于排查 _logger.error(f"Encountered exception '{str(e)}' of type {type(e)}!") return None
这些技巧覆盖了SSO凭证过期时的异常场景,可避免异常被通用块捕获,同时精准提示用户执行aws sso login操作。
内容的提问来源于stack exchange,提问作者Kevin Buchs
相关产品推荐
相关产品推荐

