将 Spring websockets (sockJS + Stomp) 与基于令牌的身份验证 (JWT) 一起使用的最佳方法

Posted

技术标签:

【中文标题】将 Spring websockets (sockJS + Stomp) 与基于令牌的身份验证 (JWT) 一起使用的最佳方法【英文标题】:Best approach to use Spring websockets (sockJS + Stomp) with token based authentication (JWT) 【发布时间】:2019-04-01 21:48:16 【问题描述】:

我想在 Spring Boot 应用程序中使用 websockets (sockJS with Stomp),该应用程序通过 Json Web Token (JWT) 进行基于令牌的身份验证。服务器上有一个过滤器来验证 JWT 令牌。这个令牌被发送到请求标头,但 SockJS 客户端 api 不支持标头。这意味着,当 SockJS 客户端 api 尝试与服务器进行 websocket 握手时,例如:

new SockJS("http://localhost:8080/websocket")

HTTP 请求将被 JWT 授权过滤器拦截,握手将失败,因为请求上没有标头,因此,请求将被过滤器拒绝。我在论坛中看到了几种解决方法,但它们似乎都不适用于这种情况:

HandshakeInterceptor:此解决方案不起作用,因为过滤器总是在拦截器之前执行。 在 STOMP 标头上发送身份验证标头也不起作用,因为 STOMP 连接自然发生在握手之后。

我发现here 可以通过查询参数在 SockJS 握手 URL 上发送令牌,我必须更改身份验证过滤器以查找查询参数,而不仅仅是标题。出于安全原因,我不太喜欢这种在查询参数上发送令牌的解决方案。有没有更好的选择,或者这真的是最好的方法吗?

【问题讨论】:

【参考方案1】:

HandshakeInterceptor:此解决方案不起作用,因为过滤器 总是在拦截器之前执行。

这就是我使用与您完全相同的设置所做的。

您需要将websocket endpoint添加到

@Override public void configure(WebSecurity registry)

喜欢

registry.ignoring().antMatchers("/websocket/**");

这将告诉 spring security 不要触发套接字端点,因此您为 jwt 设置的过滤器。

【讨论】:

以上是关于将 Spring websockets (sockJS + Stomp) 与基于令牌的身份验证 (JWT) 一起使用的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

带有 websocket 和 stockjs 的 JBOSS eap 6.3 beta - 使用 spring 框架的 stomp.js

websocket 工作原理

websocket 原理

C 实现的 WebSocket 服务器握手失败

WebSocket学习

如何将 Spring Webflux Websocket 路由作为注释?