Fencer
Fencer

Reputation: 1078

How to use Spring Security with Spring Websocket support but without STOMP?

I'm currently Building a web application that uses Spring to leverage websocket Support and security. The thing is, I don't want to use STOMP. It has not been updated for about 4 yours now and I don't need it. So I followed the answer to another Stackoverflow question to configure Spring for websockets with SockJS but without STOMP.

Now I want to integrate Spring Security for websocket authentication and authorisateion. Unfortunately the documentation is bound to configure Spring Security for STOMP-websockets.

I would highly appreciate any help with configuring Spring Security for my case. Does someone maybe know any tutorial or example for that? I did not find any yet.

Upvotes: 7

Views: 4904

Answers (2)

mrchebik
mrchebik

Reputation: 109

I will only add the answer above, having specified as I managed to solve it.

My problem was that request.getPrinciple() returned null. Having played from viewings of headings, I found cookie value. And having substituted the same cookie id value to websocket request, the server finds principle for this request.

For example, when we authorized, I make request to /auth/principal, to get data about player from database.

@GetMapping(value="/auth/principal")
    public ResponseEntity principal(HttpServletRequest request,
                                    Principal principal) {
        Player player = playerService.findByEmail(principal.getName());

        String jsonString = new JSONObject()
                .put("id", player.getId())
                .put("nickname", player.getNickname())
                .put("cookie", request.getHeader("cookie")).toString();

        return new ResponseEntity(jsonString, HttpStatus.OK);
    }

Then, on client side, when I want to connect to websocket, I specify headers of request, defining cookie (cookie: COOKIE-ID)

Upvotes: 1

biiyamn
biiyamn

Reputation: 506

Websocket messaging session starts with a Http request , therefore spring security can be used as it's a framework for securing http requests. In spring security authenticated user and its associated security context are stored in session. Authenticated is accessible from Websocket handshake because it transports http request. Spring Websocket defines HttpSessionHandshakeInterceptor which can be registred in your configuration using addInterceptors method

    @EnableWebSocket
    @Configuration
    public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry 
       webSocketHandlerRegistry) {
    webSocketHandlerRegistry.addHandler(createHandler(), 
    "/handler").addInterceptors(new HttpSessionHandshakeInterceptor() 
      {
        @Override
        public void afterHandshake(ServerHttpRequest request, 
         ServerHttpResponse response, WebSocketHandler wsHandler, 
         @Nullable Exception ex) {

            super.afterHandshake(request, response, wsHandler, ex);

        }

        @Override
        public boolean beforeHandshake(ServerHttpRequest request, 
         ServerHttpResponse response, WebSocketHandler wsHandler, 
          Map<String, Object> attributes) throws Exception {
            boolean b = super.beforeHandshake(request, response, 
         wsHandler, attributes) && 
      ((UsernamePasswordAuthenticationToken) 
    request.getPrincipal()).isAuthenticated();
            return b;
        }
         }).withSockJS();
    }

     @Bean
     public WebSocketHandler createHandler() {

    return new MyHandler();

    }
   }

you can also verify authenticated use at Handler which is stored in websocket session

Upvotes: 3

Related Questions