AWS Lambda自定义JWT验证报错:无法找到密钥对应算法
问题:AWS Lambda中JWT验证报错:无法找到密钥对应的算法
报错信息:
Unexpected error during JWT validation: Unable to find an algorithm for key: {'alg': 'RS256', 'e': 'AQAB', 'kid': 'dmAQX7bVDINFkTGxZc5YCxF5ZA/pcaRsQMUoBbRt4bw=', 'kty': 'RSA', 'n': 'u9hHbyMaI-PWsTG9MtaHjxwBmMez6VeV-ScqIgllBUSQkx8Ao...vGUIG39rb3nPmNVCunBw', 'use': 'sig'}
Lambda代码如下:
import json import os import requests from jose import jwt, jwk def get_efs_keys(file_name="/mnt/efs/jwks.json"): # The jkws.json is obtained from here: # https://cognito-idp.<Region>.amazonaws.com/<userPoolId>/.well-known/jwks.json try: with open(file_name, 'r') as file: jwks_data = json.load(file) return jwks_data.get('keys', []) except Exception as e: print(f"An error occurred while fetching keys: {e}") return [] def validate_jwt(jwt_token, keys): if not jwt_token: return False, False try: headers = jwt.get_unverified_headers(jwt_token) kid = headers.get('kid') if not kid: return False, False key = next((key for key in keys if key['kid'] == kid), None) if key is None: return False, False public_key = jwk.construct(key) decoded_token = jwt.decode(jwt_token, public_key, algorithms=['RS256'], audience=os.environ.get('APP_CLIENT_ID')) return True, decoded_token.get('sub', False) except jwt.JWTError as e: print(f"JWT token validation error: {e}") return False, False except Exception as e: print(f"Unexpected error during JWT validation: {e}") return False, False def lambda_handler(event, context): # Get all headers from the event headers = event.get('headers', {}) # Get the Authorization header authorization_header = headers.get('Authorization', '') # Parse the Bearer token to get only the access token (case-insensitive) if authorization_header.lower().startswith('bearer '): access_token = authorization_header[7:] else: access_token = None # Get keys from EFS keys = get_efs_keys() # Validate the JWT token jwt_valid, sub = validate_jwt(access_token, keys) # Create a response response_body = { 'access_token': access_token, 'jwt_valid': jwt_valid, 'sub': sub } response = { 'statusCode': 200, 'headers': { 'Content-Type': 'application/json' }, 'body': json.dumps(response_body) } return response
需求:验证成功时,jwt_valid为True,sub返回对应唯一值。请问报错原因是什么?
报错原因及解决方案
核心报错原因
- 库版本差异导致调用不兼容:Lambda环境安装的
python-jose版本和本地不一致,新版本中jwk.construct()不再支持自动从JWK字典推断算法,必须显式指定算法参数,而你的代码没有传入,导致算法匹配失败。 - 冗余的密钥构造步骤:
jwt.decode()方法本身可以直接接收JWK字典,不需要手动调用jwk.construct()生成密钥对象,这一步冗余操作反而触发了版本兼容问题。
修复后的代码(关键部分)
修改validate_jwt函数,去掉冗余的jwk.construct()调用,直接传入JWK字典到jwt.decode():
def validate_jwt(jwt_token, keys): if not jwt_token: return False, False try: headers = jwt.get_unverified_headers(jwt_token) kid = headers.get('kid') if not kid: return False, False key = next((key for key in keys if key['kid'] == kid), None) if key is None: return False, False # 直接使用JWK字典,无需构造jwk对象 decoded_token = jwt.decode( jwt_token, key, algorithms=['RS256'], audience=os.environ.get('APP_CLIENT_ID'), # 建议添加issuer验证,增强安全性,需要配置对应的环境变量 issuer=f"https://cognito-idp.{os.environ.get('REGION')}.amazonaws.com/{os.environ.get('USER_POOL_ID')}" ) return True, decoded_token.get('sub', False) except jwt.JWTError as e: print(f"JWT token validation error: {e}") return False, False except Exception as e: print(f"Unexpected error during JWT validation: {e}") return False, False
额外注意事项
- 确保Lambda层或部署包中的
python-jose版本和本地测试环境一致 - 建议添加
issuer参数验证Cognito颁发者,避免无效Token通过验证 - 检查EFS中的
jwks.json是否完整、格式正确,没有下载损坏
内容的提问来源于stack exchange,提问作者Andre
相关产品推荐
相关产品推荐

