如何在没有STOMP的情况下使用Spring Websocket支持Spring Security?

问题描述 投票:4回答:2

我目前正在构建一个使用Spring来利用websocket支持和安全性的Web应用程序。问题是,我不想使用STOMP。它现在还没有更新大约4个,我不需要它。所以我按照另一个Stackoverflow question的答案来配置带有SockJS但没有STOMP的websockets的Spring。

现在我想将Spring Security集成到websocket身份验证和授权中。不幸的是,documentation必然会为STOMP-websockets配置Spring Security。

我非常感谢为我的案例配置Spring Security的任何帮助。有人可能知道任何教程或示例吗?我还没找到。

java spring security websocket sockjs
2个回答
3
投票

Websocket消息传递会话以Http请求开始,因此可以使用spring安全性,因为它是保护http请求的框架。在Spring中,经过身份验证的用户及其关联的安全上下文存储在会话中。可以从Websocket握手访问Authenticated,因为它传输http请求。 Spring Websocket定义了HttpSessionHandshakeInterceptor,它可以使用addInterceptors方法在您的配置中注册

    @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();

    }
   }

您还可以在Handler上验证存储在websocket会话中的经过身份验证的使用


0
投票

我只会添加上面的答案,指定我设法解决它。

我的问题是request.getPrinciple()返回null。从标题的观看发挥,我发现cookie价值。并且将相同的cookie id值替换为websocket请求,服务器为此请求找到principle

例如,当我们授权时,我向/auth/principal发出请求,从数据库中获取有关玩家的数据。

@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);
    }

然后,在客户端,当我想连接到websocket时,我指定请求的标头,定义cookie(cookie:COOKIE-ID)

© www.soinside.com 2019 - 2024. All rights reserved.