I have a pretty simple requirement (I use Spring-Security 4.0.1) but I can't find any examples on the web except what is been told on this page: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-server-handler
It is relatively simple to integrate a WebSocketHandler into other HTTP serving environments with the help of WebSocketHttpRequestHandler.
What I have: An implementation of WebSocketHandler
that does the job and an HTTP serving environments using a Basic Authentication. My WebApplicationInitializer
looks like this:
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
...
// WebSocket support - Handshake
Dynamic ws = servletContext.addServlet("webSocketHttpRequestHandler", new HttpRequestHandlerServlet());
ws.addMapping("/streaming/*");
// Spring Security Filter
FilterRegistration.Dynamic springSecurity = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
springSecurity.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
}
}
This is how I plugged my websocket endpoint to my existing web application. My WebSocket configuration class looks like (very simplified) this:
@Configuration
public class WebSocketServicesConfig{
@Bean
public WebSocketHttpRequestHandler webSocketHttpRequestHandler() {
return new WebSocketHttpRequestHandler(new StreamingWebSocketHandler());
}
}
StreamingWebSocketHandler
implements WebSocketHandler
.
I also have a RESTful Web Service (in the same server) that uses the configured Basic Authentication.
What is working: My RESTful Web Service is working with any web browsers. I can do some authenticated queries (credentials can be sent in the HTTP headers).
WebSocket queries are working and ask for authentication the first time I try to do some (under FireFox, a popup appears asking for credentials, once I enter them, client and server are able to communicate via WebSocket messages).
In my WebSocketHandler
, the Spring object: WebSocketSession
that contains informations about the authenticated user is correct (#getPrincipal()
method returns a Authentication
containing the right granted Authorities, details and so on...).
Note that once the websocket is authenticated, I can relaunch the query without re-enter them.
What I want: On a user point of view, this is bad because the credentials are required twice:
- First for RESTful queries
- Second for WebSocket queries
How can I bypass the second authentication assuming the first one succeeded? Is there a way to detect the client has been authenticated and not ask for credentials?
What I don't want: I don't want to use neither Stomp over websocket nor SockJs (I don't need to support old web browsers).