我们使用弹簧4实现了websocket服务器端实现。它已配置为使用spring security for auth / authz。在客户端,我们使用sockJS,当客户端与服务器位于同一域时,它可以很好地工作。
以这种方式调用websocket ......
socket = new SockJS(" http://guest:guest@mydomain.org/MyWebSocketApp/tracker")
这最终会调用http://guest:guest@myinterestingdomain.org/MyWebSocketApp/tracker/info来决定要使用的传输。这一切都很好。
但是,当使用来自其他域的客户端时,我发现凭据被剥离了。因此,当此客户端位于不同的域上时,我看到正在进行的调用是: http://myinterestingdomain.com/MyWebSocketApp/tracker/info。我没有看到凭证被传递。因此,我得到一个401错误(未授权)用户。我们在服务器端有CORS配置,并且还有:
Access-Control-Allow-Credentials" true“
有人可以帮帮我吗?我没有选择,我不明白为什么凭证被剥夺了?这可能与CORS有关吗?
答案 0 :(得分:3)
即使XmlHttpRequest.withCredentials=true
(由SockJS客户端完成)和Access-Control-Allow-Credentials=true
,您也无法在URL中传递用于跨域请求的用户名和密码。
为了使用基本身份验证,您需要自己创建Authorization
标头,但似乎SockJS客户端目前不允许这样做。有一个问题需要这样的支持,我已经添加a new comment解释我们需要这个用于基本身份验证支持。
由于授权标头不是simple header,因此在实际请求之前将发送CORS preflight request。但是Spring框架目前默认为does not dispatch OPTIONS requests,因此即使在客户端设置了Authorization标头,您也需要在Spring Framework中启用OPTIONS请求调度。
使用web.xml
:
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
或者,如果您使用的是没有web.xml
的Servlet 3,请将其添加到扩展AbstractAnnotationConfigDispatcherServletInitializer
的类中:
@Override
protected void customizeRegistration(Dynamic registration) {
registration.setInitParameter("dispatchOptionsRequest", "true");
}