내 목표는 WebSocket 끝점을 보호하는 것입니다 ws://localhost:8080/chat
.
제가 한:
STOMP와 WebSocket 연결을 만들려고했습니다.
var socket = new SockJS("/chat"); stompClient = Stomp.over(socket); stompClient.connect({"X-XSRF-TOKEN": getCookie("XSRF-TOKEN")}, function (status) { // it should not execute. });
AbstractSecurityWebSocketMessageBrokerConfigurer
// see: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#websocket @Configuration public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer { @Override protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { messages .nullDestMatcher().authenticated() .simpDestMatchers("/app/**").hasRole("USER") .simpDestMatchers("/user/**", "/topic/channel/*").hasRole("USER") .simpTypeMatchers(MESSAGE, SUBSCRIBE).denyAll() .anyMessage().denyAll(); } }
WebSocketMessageBrokerConfigurer
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/chat").withSockJS(); // user connect to } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.setApplicationDestinationPrefixes("/app"); // user send message to registry.enableSimpleBroker("/topic", "/queue"); // user subscribe to .. for channel messages. registry.setUserDestinationPrefix("/user"); // user subscribe to .. for private messages. } }
WebSecurityConfigurerAdapter
@Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .and() .formLogin() .and() .authorizeRequests().anyRequest().authenticated(); } }
내 예상 결과는 다음과 같습니다. JSESSIONID를 보내지 않았기 때문에 WebSocket 연결이 실패해야합니다.
내 실제 결과는 다음과 같습니다 Spring Security은 사용자를 인식하고 난을 얻을 수 있습니다 UserDetails
로 (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()
.
내 질문 :
데이터베이스를 사용하려면 JSESSIONID 또는 XSRF-TOKEN?
X-XSRF-TOKEN
StompCommand.CONNECT 엔드 포인트를 보호하는 올바른 방법을 사용 하고 있습니까?Spring Security
X-XSRF-TOKEN
가JSESSIONID
. CSRF 토큰은 사이트 간 요청 위조를 방지하는 데 사용되지 않습니까?X-XSRF-TOKEN
요청 헤더에 키 없이 WebSocket 연결을 생성하면 브라우저 콘솔에서 오류가 발생 합니다.<<< ERROR message:Failed to send message to ExecutorSubscribableChannel[clientInboundChannel]; nested exception is org.springframework.security.web.csrf.InvalidCsrfTokenException\c Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-XSRF-TOKEN'. content-length:0