使用 Spring 安全性和 JWT 在 REST 中使用 <img> 标签访问私有图像
Posted
技术标签:
【中文标题】使用 Spring 安全性和 JWT 在 REST 中使用 <img> 标签访问私有图像【英文标题】:Access private images with <img> tag in REST with Spring security & JWT 【发布时间】:2017-06-25 14:45:53 【问题描述】:当前情景
Spring 项目使用 Spring Security 和 JWT 保护 REST API。这些 API 产生 JSON 响应。 UsernamePasswordAuthenticationFilter
用于验证在 Authorization
标头中发送的 JWT。经过身份验证和未经身份验证的 API 都按预期工作。
要求
现在我需要在 HTTP 响应中为登录用户发送图像。
解决方案1
发送一个byte[]
,将图像表示为值到“图像”键以及其他信息。
但是,如果图像很大,完整的 JSON 响应可能需要一些时间。
解决方案2
将链接作为值发送到“图像”键以及其他信息。客户端可以分配<img src=the_link>
,它将在单独的请求中获取大图像。然后创建一个带有@RequestMapping
的请求,对应于该链接,生成一个byte[]
。
我的问题
我更喜欢解决方案 2。但它会产生UNAUTHORIZED
异常,因为没有有效的Authorization
令牌。此外,此 API 必须经过身份验证。
经过一番搜索,找到了this,和我的要求一样。接受的答案说,
OAuth Bearer Token 规范支持将令牌作为查询参数发送。
这是我必须做的吗?
在我的 Spring 过滤器中,从Authorization
标头获取 JWT,如果是
空,从request.getParameter()
获取
在第一个 JSON 响应中
API,发送"image":"http://ip/getImage?token=dbscsbCXV"
创建 API @GetMapping("getImage") byte[] getImage()
或者有没有更好的方法? 请指导我。
【问题讨论】:
【参考方案1】:如果您:
为您的服务器使用 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 提供内容,而不是每次都访问您的服务器以获取流式图像。 即使用于身份验证的 JWT 令牌发生更改,URL 也会继续工作您可能认为这不如使用按呼叫身份验证安全,但如果 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)
【讨论】:
感谢@FrederikHeremans。在尝试您的建议并参考链接后会回来。以上是关于使用 Spring 安全性和 JWT 在 REST 中使用 <img> 标签访问私有图像的主要内容,如果未能解决你的问题,请参考以下文章
Spring(Websockets / REST / Security)、JWT 和 Sockjs(Stomp)集成
使用 Spring Boot 和 JWT 保护 REST Api