EnableWebSocketMessageBroker Vs EnableWebSocketSecurity

koonlx·2024년 9월 24일

stay_connect

목록 보기
9/10
  implementation 'org.springframework.boot:spring-boot-starter-websocket'
  implementation 'org.springframework.security:spring-security-messaging'

Spring Boot에서 Socket통신을 구현할 때 위 두 종속성을 자주 사용하는거 같아서 각 종속성의 역할을 알아보고자 한다.
Messaging Stomp Websocket을 참고하면 이해가 더 잘 될 것이다.

1. @EnableWebSocketMessageBroker

이 예약어는 implementation 'org.springframework.boot:spring-boot-starter-websocket' 종속성을 사용한 Socket 연결을 설정할 때 사용하는 주석이다.
@EnableWebSocketMessageBroker는 WebSocket 메시징 아키텍처에서 중요한 역할을 하는 설정이다. 이 설정은 메시지 브로커(Message Broker) 를 통해 실시간으로 메시지를 주고받을 수 있는 환경을 구축하는 데 사용된다. 만약 STOMP를 사용하지 않고 싶다면 @EnableWebSocket를 사용하면 된다.

예시로

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/ws"); // WebSocket 핸들러 등록
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MyWebSocketHandler(); // 메시지 처리 로직을 가진 핸들러 구현
    }
}

주로 STOMP (Simple Text Oriented Messaging Protocol) 를 사용하는 메시지 통신을 처리하고, WebSocket 메시지가 어떤 경로로 전송되고, 어떤 방식으로 처리될지 결정한다. 즉, WebSocket 연결이 이루어진 후 실제 메시지들이 서버와 클라이언트 사이에서 어떻게 라우팅되는지를 관리한다.

STOMP 프로토콜 기반 통신에 대해 아래의 처리를 담당한다.

  • 메시지 브로커 설정: WebSocket에서 들어오는 메시지를 라우팅하거나 브로드캐스팅하는 역할을 한다. 메시지 브로커는 클라이언트 간의 메시지 전달을 중계해준다.
  • STOMP 프로토콜 지원: Spring WebSocket에서는 STOMP라는 메시지 프로토콜을 지원하며, 이를 통해 클라이언트는 서버로 메시지를 보내고 특정 주제를 구독할 수 있다.
  • 메시지 라우팅: 메시지를 특정 주제(topic) 또는 큐(queue)로 라우팅하거나, 특정 클라이언트에게 메시지를 전달할 수 있다.

동작 과정

  • 클라이언트가 WebSocket을 통해 서버에 연결된 후, STOMP 메시지를 주고받기 위한 경로가 설정된다.
  • 메시지 라우팅: 서버는 클라이언트의 메시지를 받아 적절한 구독자에게 메시지를 전달한다. 예를 들어, 사용자가 /app/chat 경로로 메시지를 보내면, 서버는 이 메시지를 처리하고 /topic/messages 구독자들에게 전송한다.
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic", "/queue");  // 클라이언트 구독 가능 경로
        config.setApplicationDestinationPrefixes("/app");  // 클라이언트가 서버에 메시지를 보낼 때 사용할 경로
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").withSockJS();  // 클라이언트가 연결할 WebSocket 엔드포인트
    }
}
package com.example.springstompchat.controller;

import com.example.springstompchat.model.ChatMessage;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class ChatController {

    @MessageMapping("/chat")
    @SendTo("/topic/messages")
    public ChatMessage sendMessage(ChatMessage message) {
        return message;
    }
}

세부 설명:

  1. enableSimpleBroker("/topic", "/queue"): 메시지 브로커를 설정한다. 여기서 "/topic"과 "/queue"는 메시지가 전송되는 목적지다. 클라이언트는 이 경로를 구독해서 메시지를 받을 수 있다.
  2. setApplicationDestinationPrefixes("/app"): 클라이언트가 서버로 메시지를 보낼 때 사용할 경로를 설정한다. 클라이언트는 /app/chat 같은 경로로 메시지를 보낼 수 있으며, 서버에서 이 메시지를 처리한다.
  3. registerStompEndpoints: 클라이언트가 WebSocket에 연결하기 위한 엔드포인트를 설정한다. 예를 들어, 클라이언트는 /ws 경로로 연결을 시도할 수 있다.

메시지 흐름

  1. 클라이언트 -> 서버: 클라이언트가 /app/chat 경로로 메시지를 보내면, 서버는 이를 받아 처리한다.
  2. 서버 -> 클라이언트: 서버는 처리한 메시지를 /topic/messages와 같은 주제로 구독한 클라이언트에게 브로드캐스팅한다.

이 설정은 메시지 브로커를 이용해 WebSocket 통신에서 메시지를 처리하고 라우팅하는 핵심적인 역할을 담당한다. 이때 보안적인 부분은 신경 쓰지 않으며, 오직 메시지의 경로와 라우팅 규칙만 처리한다.


2. @EnableWebSocketSecurity

@EnableWebSecurity 설정은 http 프로토콜 통신에서 보안설정을 한다면 @EnableWebSocketSecurity는 ws 프로토콜 통신에서의 보안설정을 담당한다.

연결된 후 WebSocket을 통해 주고받는 메시지에 대한 접근 권한을 제어한다. 예를 들어, 특정 사용자만 특정 경로의 메시지에 접근하도록 설정할 수 있다. 즉 STOMP 프로토콜 레벨에서의 권한 설정이 가능하다.

간단 예제

@Configuration
public class WebSocketSecurityConfig {

    @Bean
    public AuthorizationManager<Message<?>> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) {
        messages
                .nullDestMatcher().authenticated() 
                .simpSubscribeDestMatchers("/user/queue/errors").permitAll() 
                .simpDestMatchers("/app/**").hasRole("USER") 
                .simpSubscribeDestMatchers("/user/**", "/topic/friends/*").hasRole("USER") 
                .simpTypeMatchers(MESSAGE, SUBSCRIBE).denyAll() 
                .anyMessage().denyAll(); 

        return messages.build();
    }
}

해당 예제 코드는 WebSocket Security에서 제공하고 있다.
위 코드와 같이 세부적인 경로에 따른 권한 설정이 가능하다.


결론

결론적으로 'org.springframework.boot:spring-boot-starter-websocket'는 WebSocket,STOMP 설정과 3-Way-Handshake 전후 처리를 할 수 있고, 'org.springframework.security:spring-security-messaging'는 STOMP기반 통신에 있어서 경로별로 권한설정을 할 수 있는 부분이 핵심이다.

profile
Server Developer

0개의 댓글