使用 <img> Spring 安全性和 JWT 访问 REST 中带有标签的私有映像



当前场景

一个 Spring 项目使用 Spring 安全性和 JWT 保护 REST API。这些 API 生成 JSON 响应。实现UsernamePasswordAuthenticationFilter用于验证在标头中发送AuthorizationJWT。经过身份验证和未经身份验证的 API 都按预期工作。

要求

现在我需要在HTTP响应中为登录用户发送图像。

解决方案1

发送了一个byte[],将图像表示为"图像">的值以及其他信息。 但是,如果图像很大,则可能需要一些时间才能完成完整的 JSON 响应。

解决方案2

已将链接作为值发送到"图像">以及其他信息。客户端可以分配<img src=the_link>,这将应该在单独的请求中获取大图像。然后创建一个带有@RequestMapping的请求,对应于该链接,这将产生一个byte[]

我的问题

我更喜欢解决方案2。但它会产生UNAUTHORIZED异常,因为没有有效的Authorization令牌。此外,此 API 必须经过身份验证。

经过一番搜索,发现了这一点,这与我的要求相同。接受的答案说,

OAuth 持有者令牌规范支持将令牌作为查询参数发送。

这是我必须做的吗?

  • 在我的 Spring 过滤器中,从Authorization标头中获取 JWT,如果是 空的,从request.getParameter()中获取
  • 在第一个的 JSON 响应中 API,发送"image":"http://ip/getImage?token=dbscsbCXV"
  • 创建 API@GetMapping("getImage") byte[] getImage()

还是有更好的方法? 请指导我。

如果您

  • 对服务器使用 HTTPS,否则请求标头中的 JWT 令牌将被公开(授权标头也是如此)。
  • 当令牌更改时,不要介意图像 URL 不再有效

另一种方法可能是生成一个具有足够熵的随机键(例如,将 3 个 UUID 合并为一个字符串)并将其与您的 Image 实体一起存储,从您的 REST 服务返回它,例如:

https://ip/images/824b6854-edcc-11e6-bc64-92361f0026713567fef0-549a-4cdb-9264-5e15166dfd6f/the-file-name.pdf

确保禁用这些"公共"路径的 Spring 安全过滤器。

这种方法的优点:

  • 无需检查此资源的身份验证
  • (如果图像变化不大) 您可以将其缓存或通过 CDN 提供内容,而不是每次都只为流式传输图像而访问您的服务器。
  • URL 将继续工作,即使用于身份验证的 JWT 令牌发生变化

您可能认为这不如使用每次调用身份验证安全,但如果 ID 有足够的熵,它是防水的。Facebook也使用这个概念(https://www.quora.com/Are-Facebook-pictures-really-private-and-are-they-hosted-on-Facebook-servers,https://en.wikipedia.org/wiki/Capability-based_security)

最新更新