Check SockJS session type
This commits adds a validation check whether the SockJS session type matches the transport type and rejects requests for which they don't match. Issue: SPR-14867
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -43,6 +43,14 @@ public interface TransportHandler {
|
||||
*/
|
||||
TransportType getTransportType();
|
||||
|
||||
/**
|
||||
* Whether the type of the given session matches the transport type of this
|
||||
* {@code TransportHandler} where session id and the transport type are
|
||||
* extracted from the SockJS URL.
|
||||
* @since 4.3.3
|
||||
*/
|
||||
boolean checkSessionType(SockJsSession session);
|
||||
|
||||
/**
|
||||
* Handle the given request and delegate messages to the provided
|
||||
* {@link WebSocketHandler}.
|
||||
|
||||
@@ -291,6 +291,11 @@ public class TransportHandlingSockJsService extends AbstractSockJsService implem
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!transportHandler.checkSessionType(session)) {
|
||||
logger.debug("Session type does not match the transport type for the request.");
|
||||
response.setStatusCode(HttpStatus.NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (transportType.sendsNoCacheInstruction()) {
|
||||
@@ -303,7 +308,10 @@ public class TransportHandlingSockJsService extends AbstractSockJsService implem
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transportHandler.handleRequest(request, response, handler, session);
|
||||
|
||||
|
||||
chain.applyAfterHandshake(request, response, null);
|
||||
}
|
||||
catch (SockJsException ex) {
|
||||
|
||||
@@ -99,4 +99,9 @@ public abstract class AbstractHttpReceivingTransportHandler extends AbstractTran
|
||||
|
||||
protected abstract HttpStatus getResponseStatus();
|
||||
|
||||
@Override
|
||||
public boolean checkSessionType(SockJsSession session) {
|
||||
return session instanceof AbstractHttpSockJsSession;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@ import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
|
||||
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
|
||||
import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig;
|
||||
import org.springframework.web.socket.sockjs.transport.SockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.TransportType;
|
||||
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.session.StreamingSockJsSession;
|
||||
|
||||
/**
|
||||
@@ -47,6 +49,11 @@ public class EventSourceTransportHandler extends AbstractHttpSendingTransportHan
|
||||
return new MediaType("text", "event-stream", StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkSessionType(SockJsSession session) {
|
||||
return session instanceof EventSourceStreamingSockJsSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamingSockJsSession createSession(
|
||||
String sessionId, WebSocketHandler handler, Map<String, Object> attributes) {
|
||||
|
||||
@@ -32,9 +32,11 @@ import org.springframework.web.socket.sockjs.SockJsTransportFailureException;
|
||||
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
|
||||
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
|
||||
import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig;
|
||||
import org.springframework.web.socket.sockjs.transport.SockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.TransportHandler;
|
||||
import org.springframework.web.socket.sockjs.transport.TransportType;
|
||||
import org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.session.StreamingSockJsSession;
|
||||
import org.springframework.web.util.JavaScriptUtils;
|
||||
|
||||
@@ -88,6 +90,11 @@ public class HtmlFileTransportHandler extends AbstractHttpSendingTransportHandle
|
||||
return new MediaType("text", "html", StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkSessionType(SockJsSession session) {
|
||||
return session instanceof HtmlFileStreamingSockJsSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamingSockJsSession createSession(
|
||||
String sessionId, WebSocketHandler handler, Map<String, Object> attributes) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.web.socket.sockjs.SockJsException;
|
||||
import org.springframework.web.socket.sockjs.SockJsTransportFailureException;
|
||||
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
|
||||
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
|
||||
import org.springframework.web.socket.sockjs.transport.SockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.TransportType;
|
||||
import org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
|
||||
@@ -53,6 +54,11 @@ public class JsonpPollingTransportHandler extends AbstractHttpSendingTransportHa
|
||||
return new MediaType("application", "javascript", StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkSessionType(SockJsSession session) {
|
||||
return session instanceof PollingSockJsSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PollingSockJsSession createSession(
|
||||
String sessionId, WebSocketHandler handler, Map<String, Object> attributes) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -103,6 +103,11 @@ public class WebSocketTransportHandler extends AbstractTransportHandler
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkSessionType(SockJsSession session) {
|
||||
return session instanceof WebSocketServerSockJsSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSockJsSession createSession(String id, WebSocketHandler handler, Map<String, Object> attrs) {
|
||||
return new WebSocketServerSockJsSession(id, getServiceConfig(), handler, attrs);
|
||||
|
||||
@@ -24,8 +24,10 @@ import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
|
||||
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
|
||||
import org.springframework.web.socket.sockjs.transport.SockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.TransportHandler;
|
||||
import org.springframework.web.socket.sockjs.transport.TransportType;
|
||||
import org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
|
||||
|
||||
/**
|
||||
@@ -51,6 +53,11 @@ public class XhrPollingTransportHandler extends AbstractHttpSendingTransportHand
|
||||
return new DefaultSockJsFrameFormat("%s\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkSessionType(SockJsSession session) {
|
||||
return session instanceof PollingSockJsSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PollingSockJsSession createSession(
|
||||
String sessionId, WebSocketHandler handler, Map<String, Object> attributes) {
|
||||
|
||||
@@ -25,8 +25,10 @@ import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
|
||||
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
|
||||
import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig;
|
||||
import org.springframework.web.socket.sockjs.transport.SockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.TransportHandler;
|
||||
import org.springframework.web.socket.sockjs.transport.TransportType;
|
||||
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
|
||||
import org.springframework.web.socket.sockjs.transport.session.StreamingSockJsSession;
|
||||
|
||||
/**
|
||||
@@ -57,6 +59,11 @@ public class XhrStreamingTransportHandler extends AbstractHttpSendingTransportHa
|
||||
return new MediaType("application", "javascript", StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkSessionType(SockJsSession session) {
|
||||
return session instanceof XhrStreamingSockJsSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamingSockJsSession createSession(
|
||||
String sessionId, WebSocketHandler handler, Map<String, Object> attributes) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,7 @@ import static org.junit.Assert.*;
|
||||
import static org.mockito.BDDMockito.*;
|
||||
|
||||
/**
|
||||
* Test fixture for {@link org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService}.
|
||||
* Test fixture for {@link DefaultSockJsService}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sebastien Deleuze
|
||||
@@ -239,6 +239,7 @@ public class DefaultSockJsServiceTests extends AbstractHttpRequestTests {
|
||||
resetResponse();
|
||||
sockJsPath = sessionUrlPrefix + "xhr_send";
|
||||
setRequest("POST", sockJsPrefix + sockJsPath);
|
||||
given(this.xhrSendHandler.checkSessionType(this.session)).willReturn(true);
|
||||
this.service.handleRequest(this.request, this.response, sockJsPath, this.wsHandler);
|
||||
|
||||
assertEquals(200, this.servletResponse.getStatus()); // session exists
|
||||
|
||||
Reference in New Issue
Block a user