部署到AWS Elastic Beanstalk后CloudFront签名URL生成报500错误
检查私钥文件的读取权限
Elastic Beanstalk的应用运行用户(如tomcat或appuser)可能没有私钥文件的读取权限。登录EB实例,用ls -l <文件路径>查看权限设置,确保运行用户拥有至少读权限。如果权限不足,可通过.ebextensions配置文件在部署时自动设置权限,比如创建.ebextensions/01-set-permissions.config:container_commands: 01_set_key_permissions: command: "chmod 600 /path/to/private-key.pem && chown appuser:appuser /path/to/private-key.pem"验证私钥文件路径的正确性
本地开发环境的文件路径和EB实例的路径可能存在差异。在代码中添加日志输出实际路径:System.err.println("Private key file absolute path: " + new File(privateKeyFilePath).getAbsolutePath());部署后查看EB日志,确认该路径下确实存在私钥文件。注意EB应用的工作目录通常是
/var/app/current/,相对路径会基于此目录解析。确认私钥文件已被正确打包
如果私钥文件放在src/main/resources目录下,检查Maven/Gradle的构建配置,确保文件被包含在最终的JAR/WAR包中。可以解压部署包,查看是否有该文件。如果是外部文件,需确保部署时通过EB控制台或CLI将文件上传到实例的对应位置。查看详细错误堆栈信息
500错误的具体原因隐藏在EB的日志中:- 登录AWS控制台,进入目标Elastic Beanstalk环境
- 点击左侧菜单的“日志”,选择“请求日志”或“完整日志”下载查看
找到RuntimeException: Can't generate signed URL对应的堆栈跟踪,若为FileNotFoundException则是路径/文件存在问题;若为InvalidKeyException则可能是私钥内容损坏或权限不足。
改用类路径资源流读取私钥
避免直接使用File类访问文件,改用类路径资源流读取,适配JAR包内的资源访问:@Value("${cloud.front.distribution.domain}") String distributionDomain; @Value("${cloud.front.key.pair.id}") private String keyPairId; try (InputStream privateKeyStream = getClass().getResourceAsStream("/private-key.pem")) { if (privateKeyStream == null) { throw new RuntimeException("Private key not found in classpath"); } return CloudFrontUrlSigner.getSignedURLWithCannedPolicy( SignerUtils.Protocol.https, distributionDomain, privateKeyStream, fileName, keyPairId, calendar.getTime() ); } catch (Exception e) { throw new RuntimeException("Can't generate signed URL", e); }注意将私钥文件放在
src/main/resources目录下,并确保构建时被打包进JAR。验证环境变量配置
检查EB环境中是否正确配置了cloud.front.private.key.filePath、cloud.front.key.pair.id等环境变量,避免因变量值错误导致路径或密钥ID无效。可在代码中添加日志输出变量值进行验证。
内容的提问来源于stack exchange,提问作者Roman2904

