在进行跨域请求时,如何使用 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?的主要内容,如果未能解决你的问题,请参考以下文章