【发布时间】:2020-10-16 15:02:11
【问题描述】:
我正在使用 Akka Http 处理存储在 GCS(Google 云存储)中的文本资源的签名 URL 的重定向。基本上,我在 GCS 中有一些文件,我想在请求时与我的 API 一起提供。不幸的是,该资源的路径有一个子目录,其中包含= 字符,例如:https://storage.googleapis.com/path_start/more_path/format=avro/still_more_path/filename.avro。
Google 存储的signUrl 方法将这个= 字符编码为签名网址中的%3D。我已经验证使用这个签名的 url 允许访问 GCS 中的文件(点击它开始下载)。问题是当 Akka Http 根据请求重定向这个签名的 url 时,它会将其解码回等号。这会导致来自 GCS 的 SignatureDoesNotMatch 错误:
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message>
我尝试生成签名的 url 并在以下代码 sn-p 中重定向它:
val signedUrl = cloudStorageService.getSignedUrl(bucketId, filePath)
logger.info(s"signedUrl: $signedUrl")
redirect(signedUrl, TemporaryRedirect)
我的cloudStorageService.getSignedUrl方法在这里单独定义:
def getSignedUrl(bucket: String, path: String, expiration: Option[Int] = None): String = {
val maxLifetime = 60 * 60 * 24 * 7
val lifetime = expiration.getOrElse(maxLifetime)
val cappedExpiration = Math.min(lifetime, maxLifetime)
val blobInfo = BlobInfo.newBuilder(BlobId.of(bucket, path)).build
storage.signUrl(blobInfo, cappedExpiration, TimeUnit.SECONDS, Storage.SignUrlOption.withV4Signature).toString
}
第一个 sn-p 中的日志记录语句显示签名 URL 是使用 %3D 生成的,但重定向的 URL 已被百分比解码回 =,从而导致 SignatureDoesNotMatch 错误。
这种行为是 Akka Http 的标准行为。根据 Uri 类的the documentation,所有成员都代表解码元素的百分比。可以选择使用原始查询字符串构造 uri,但在我的情况下,编码字符发生在 uri 路径本身,而不是查询中。
所以我的问题是,有没有办法让 Akka Http 重定向这个签名的 url 而无需对路径进行百分比解码?还是我弄错了,还有其他方法可以解决这个问题?
【问题讨论】:
-
我看到的一个建议是使用 Synthetic Header such as Raw-Request-URI 作为绕过 url 规范化的一种方式。但是,似乎不允许这些标头进行重定向。尝试添加此标头时,我收到一条警告,提示“响应中不允许使用原始请求 URI”。还有其他方法可以在重定向中利用此类标头吗?
标签: scala akka urlencode akka-http