簡體   English   中英

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

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

我目前正在構建一個使用Spring來利用websocket支持和安全性的Web應用程序。 問題是,我不想使用STOMP。 它現在還沒有更新大約4個,我不需要它。 所以我按照另一個Stackoverflow 問題的答案來配置帶有SockJS但沒有STOMP的websockets的Spring。

現在我想將Spring Security集成到websocket身份驗證和授權中。 不幸的是, 文檔必然會為STOMP-websockets配置Spring Security。

我非常感謝為我的案例配置Spring Security的任何幫助。 有人可能知道任何教程或示例嗎? 我還沒找到。

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會話中的經過身份驗證的使用

我只會添加上面的答案,指定我設法解決它。

我的問題是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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM