在进行跨域请求时,如何使用 SockJS 和 STOMP 添加 Spring Security JSESSIONID?

Posted

技术标签:

【中文标题】在进行跨域请求时,如何使用 SockJS 和 STOMP 添加 Spring Security JSESSIONID?【英文标题】:How can I add a spring security JSESSIONID with SockJS and STOMP when doing a cross-domain request? 【发布时间】:2014-10-14 02:00:32 【问题描述】:

我遇到以下问题。我将描述 3 个用例 - 两个有效,另一个无效。

我有一个使用 SockJS 和 STOMP 的 AngularJS 客户端。在后端,我有一个 Spring 应用程序。客户端在 domainA.com 中,后端在 domainB.com 中。

var socket = new SockJS(("http://domainB.com/myApp/messages"));
stompClient = Stomp.over(socket);
stompClient.connect('guest', 'guest', function(frame) 
    ...

在后端有 Cors 过滤器,并且可以进行跨域调用。一切正常。

用例 1. 客户端域A,服务器域B

我的应用程序在后端不安全。我订阅如下:

stompClient.subscribe('/topic/listen', function(message) 
    showMessage(JSON.parse(message.body).content);
);

一切正常。

用例 2。 客户端域 B,服务器域 B

我的应用程序通过 Spring 安全性在后端得到保护。身份验证通过表单完成 - 用户名和密码。没有什么不寻常的。

在这种情况下,客户端在 domainB.com 上,与后端相同。一切正常,不同的是我使用了不同的订阅方式:

stompClient.subscribe('/user/queue/listen', function(message) 
    showMessage(JSON.parse(message.body).content);
);

为了从安全会话中获取委托人中受益。一切正常。没有问题。

JSESSIONID cookie 被添加到 new SockJS(("http://domainB.com/myApp/messages")); 中的连接请求中。

用例 3. 客户端域A,服务器域B

应用程序的安全性与 UC2 中相同。但是,客户端现在位于不同的域中。

JSESSIONID 添加到连接请求中。 Spring 中与 websocket 的连接未经身份验证并重定向回登录页面。这会重复并导致无法连接。

在这种情况下,为什么 JSESSIONID cookie 没有填充 与 websocket 请求?

干杯 亚当

【问题讨论】:

【参考方案1】:

我想你会在这里找到你正在寻找的答案:http://spring.io/blog/2014/09/16/preview-spring-security-websocket-support-sessions

实现 HandshakeInterceptor 的技巧

【讨论】:

【参考方案2】:

作为 SockJS 协议的一部分,http GET 被发送到 websocket 服务器以协商支持的协议。它是使用XmlHttpRequest 完成的,它不会添加存储在与其自己的域不同的域中的任何cookie,由于same-origin policy 在每个现代Web 浏览器中都实现了,因此会提供Web 应用程序和脚本。

您应该使用circumventing the same-origin policy 的方式。

【讨论】:

以上是关于在进行跨域请求时,如何使用 SockJS 和 STOMP 添加 Spring Security JSESSIONID?的主要内容,如果未能解决你的问题,请参考以下文章

开发那些事儿:前端开发环境sockjs-node报错跨域问题,该如何解决?

使用 SockJS 提供 auth 标头

Spring WebSocket入门 转载

SockJS实践:即时通信关键点

vue跨域解决方法

浏览器控制台出错,请求 /sockjs-node/info?t=1555629946494