问题
We have a websocket server side implementation using spring 4. It has been configured to use spring security for auth/authz. On the client side, we use sockJS which works perfectly when the client is in the same domain as the server.
Call to websocket is made this way…
socket = new SockJS("http://guest:guest@mydomain.org/MyWebSocketApp/tracker")
This eventually makes a call to http://guest:guest@myinterestingdomain.org/MyWebSocketApp/tracker/info to decide the transport to use. All this is good.
However, when using client from a different domain, I see that the credentials get stripped out. So, when this client is on a different domain, I see that the call being made is: http://myinterestingdomain.com/MyWebSocketApp/tracker/info. I do not see the credentials being passed. Due to this, I get a 401 error (unauthorized) user. We have the CORS configuration on the server side and also have:
Access-Control-Allow-Credentials "true”
Can someone please help me? I am out of options and I don’t understand why the credentials are getting stripped out? Could this be related to CORS?
回答1:
Even if XmlHttpRequest.withCredentials=true
(done by the SockJS client) and Access-Control-Allow-Credentials=true
, you can't pass username and password in the URL for cross domain requests.
In order to use basic authentication, you need to create yourself the Authorization
header, but it seems SockJS client does not allow this currently. There is an issue asking for such support, I have added a new comment explaining we need this for Basic Authentication support.
Since Authorization header is not a simple header, a CORS preflight request will be sent before the actual request. But Spring Framework currently does not dispatch OPTIONS requests by default, so even with the Authorization header set on client side, you will also need to enable OPTIONS requests dispatching in Spring Framework.
With 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>
Or if you are using Servlet 3 without web.xml
, add this to your class that extends AbstractAnnotationConfigDispatcherServletInitializer
:
@Override
protected void customizeRegistration(Dynamic registration) {
registration.setInitParameter("dispatchOptionsRequest", "true");
}
来源:https://stackoverflow.com/questions/26500954/sockjs-not-passing-credential-information-when-on-a-different-domaincors