How to Authenticate WebSocket in an Existing HTTP Environment with Spring Security

I have a fairly simple requirement (I'm using Spring-Security 4.0.1), but I can't find any examples on the web other than what this page said: http://docs.spring.io/spring/docs/ current / spring-framework-reference / html / websocket.html # websocket-server-handler

It is relatively easy to integrate a WebSocketHandler into another HTTP Serving Service using the WebSocketHttpRequestHandler.

What do I have . An implementation WebSocketHandler

that runs the job and the HTTP serving framework using basic authentication. Mine 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 connected the websocket endpoint to an existing web application. My WebSocket config class looks like (very simplified):

@Configuration
public class WebSocketServicesConfig{
    @Bean
    public WebSocketHttpRequestHandler webSocketHttpRequestHandler() {
        return new WebSocketHttpRequestHandler(new StreamingWebSocketHandler());
    }
}

      

StreamingWebSocketHandler

implements WebSocketHandler

.

I also have a RESTful web service (on the same server) that uses basic authentication configured.

What works . My RESTful web service works with any web browsers. I can make some authenticated requests (credentials can be sent in HTTP headers). WebSocket requests work and ask for authentication the first time I try it (FireFox pops up asking for credentials, as soon as I enter them, client and server can communicate via WebSocket messages). In my WebSocketHandler

Spring object: WebSocketSession

which contains information about authenticated user is correct (method #getPrincipal()

returns Authentication

containing rights granted to Authority, data, etc.). Please note that once the website is authenticated, I can rerun the request without re-entering.

What I want . From a user perspective, this is bad because the credentials are required twice:

  • First for RESTful requests
  • Second for WebSocket requests

How can I bypass the second authentication, assuming the first one succeeded? Is there a way to detect that the client is authenticated and not asking for credentials?

I don’t want to . I don't want to use Stomp over websocket and SockJs (I don't need to support old web browsers).

+3


source to share





All Articles