Browse Source
Of note is that this commit unrolls three Spock @Unroll-parameterized tests into a separate test for each parameter. Issue: gh-4939pull/5084/head
25 changed files with 1315 additions and 560 deletions
@ -1,560 +0,0 @@ |
|||||||
package org.springframework.security.config.websocket |
|
||||||
|
|
||||||
import static org.mockito.Mockito.* |
|
||||||
|
|
||||||
import org.springframework.beans.BeansException |
|
||||||
import org.springframework.beans.factory.config.BeanDefinition |
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory |
|
||||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException |
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry |
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor |
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition |
|
||||||
import org.springframework.core.MethodParameter |
|
||||||
import org.springframework.core.task.SyncTaskExecutor |
|
||||||
import org.springframework.http.server.ServerHttpRequest |
|
||||||
import org.springframework.http.server.ServerHttpResponse |
|
||||||
import org.springframework.messaging.Message |
|
||||||
import org.springframework.messaging.MessageDeliveryException |
|
||||||
import org.springframework.messaging.handler.annotation.MessageMapping |
|
||||||
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver |
|
||||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor |
|
||||||
import org.springframework.messaging.simp.SimpMessageType |
|
||||||
import org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler |
|
||||||
import org.springframework.messaging.support.ChannelInterceptor |
|
||||||
import org.springframework.messaging.support.GenericMessage |
|
||||||
import org.springframework.mock.web.MockHttpServletRequest |
|
||||||
import org.springframework.mock.web.MockHttpServletResponse |
|
||||||
import org.springframework.security.access.AccessDeniedException |
|
||||||
import org.springframework.security.access.expression.SecurityExpressionOperations; |
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken |
|
||||||
import org.springframework.security.config.AbstractXmlConfigTests |
|
||||||
import org.springframework.security.core.Authentication |
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal |
|
||||||
import org.springframework.security.core.context.SecurityContextHolder |
|
||||||
import org.springframework.security.messaging.access.expression.DefaultMessageSecurityExpressionHandler; |
|
||||||
import org.springframework.security.messaging.access.expression.MessageSecurityExpressionRoot; |
|
||||||
import org.springframework.security.web.csrf.CsrfToken |
|
||||||
import org.springframework.security.web.csrf.DefaultCsrfToken |
|
||||||
import org.springframework.security.web.csrf.InvalidCsrfTokenException |
|
||||||
import org.springframework.stereotype.Controller |
|
||||||
import org.springframework.util.AntPathMatcher |
|
||||||
import org.springframework.web.servlet.HandlerMapping |
|
||||||
import org.springframework.web.socket.WebSocketHandler |
|
||||||
import org.springframework.web.socket.server.HandshakeFailureException |
|
||||||
import org.springframework.web.socket.server.HandshakeHandler |
|
||||||
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor |
|
||||||
import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler |
|
||||||
import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler |
|
||||||
import org.springframework.web.socket.sockjs.transport.handler.SockJsWebSocketHandler |
|
||||||
|
|
||||||
import spock.lang.Unroll |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* @author Rob Winch |
|
||||||
*/ |
|
||||||
class WebSocketMessageBrokerConfigTests extends AbstractXmlConfigTests { |
|
||||||
Authentication messageUser = new TestingAuthenticationToken('user','pass','ROLE_USER') |
|
||||||
boolean useSockJS = false |
|
||||||
CsrfToken csrfToken = new DefaultCsrfToken('headerName', 'paramName', 'token') |
|
||||||
|
|
||||||
def cleanup() { |
|
||||||
SecurityContextHolder.clearContext() |
|
||||||
} |
|
||||||
|
|
||||||
def 'websocket with no id automatically integrates with clientInboundChannel'() { |
|
||||||
setup: |
|
||||||
websocket { |
|
||||||
'intercept-message'(pattern:'/permitAll',access:'permitAll') |
|
||||||
'intercept-message'(pattern:'/denyAll',access:'denyAll') |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
when: 'message is sent to the denyAll endpoint' |
|
||||||
clientInboundChannel.send(message('/denyAll')) |
|
||||||
|
|
||||||
then: 'access is denied to the denyAll endpoint' |
|
||||||
def e = thrown(MessageDeliveryException) |
|
||||||
e.cause instanceof AccessDeniedException |
|
||||||
|
|
||||||
and: 'access is granted to the permitAll endpoint' |
|
||||||
clientInboundChannel.send(message('/permitAll')) |
|
||||||
} |
|
||||||
|
|
||||||
def 'anonymous authentication supported'() { |
|
||||||
setup: |
|
||||||
websocket { |
|
||||||
'intercept-message'(pattern:'/permitAll',access:'permitAll') |
|
||||||
'intercept-message'(pattern:'/denyAll',access:'denyAll') |
|
||||||
} |
|
||||||
messageUser = null |
|
||||||
|
|
||||||
when: 'message is sent to the permitAll endpoint with no user' |
|
||||||
clientInboundChannel.send(message('/permitAll')) |
|
||||||
|
|
||||||
then: 'access is granted' |
|
||||||
noExceptionThrown() |
|
||||||
} |
|
||||||
|
|
||||||
@Unroll |
|
||||||
def "message type - #type"(SimpMessageType type) { |
|
||||||
setup: |
|
||||||
websocket { |
|
||||||
'intercept-message'('type': type.toString(), access:'permitAll') |
|
||||||
'intercept-message'(pattern:'/**', access:'denyAll') |
|
||||||
} |
|
||||||
messageUser = null |
|
||||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(type) |
|
||||||
if(SimpMessageType.CONNECT == type) { |
|
||||||
headers.setNativeHeader(csrfToken.headerName, csrfToken.token) |
|
||||||
} |
|
||||||
Message message = message(headers, '/permitAll') |
|
||||||
|
|
||||||
when: 'message is sent to the permitAll endpoint with no user' |
|
||||||
clientInboundChannel.send(message) |
|
||||||
|
|
||||||
then: 'access is granted' |
|
||||||
noExceptionThrown() |
|
||||||
|
|
||||||
where: |
|
||||||
type << SimpMessageType.values() |
|
||||||
} |
|
||||||
|
|
||||||
@Unroll |
|
||||||
def "pattern and message type - #type"(SimpMessageType type) { |
|
||||||
setup: |
|
||||||
websocket { |
|
||||||
'intercept-message'(pattern: '/permitAll', 'type': type.toString(), access:'permitAll') |
|
||||||
'intercept-message'(pattern:'/**', access:'denyAll') |
|
||||||
} |
|
||||||
|
|
||||||
when: 'message is sent to the permitAll endpoint with no user' |
|
||||||
clientInboundChannel.send(message('/permitAll', type)) |
|
||||||
|
|
||||||
then: 'access is granted' |
|
||||||
noExceptionThrown() |
|
||||||
|
|
||||||
when: 'message sent to other message type' |
|
||||||
clientInboundChannel.send(message('/permitAll', SimpMessageType.UNSUBSCRIBE)) |
|
||||||
|
|
||||||
then: 'does not match' |
|
||||||
MessageDeliveryException e = thrown() |
|
||||||
e.cause instanceof AccessDeniedException |
|
||||||
|
|
||||||
when: 'message is sent to other pattern' |
|
||||||
clientInboundChannel.send(message('/other', type)) |
|
||||||
|
|
||||||
then: 'does not match' |
|
||||||
MessageDeliveryException eOther = thrown() |
|
||||||
eOther.cause instanceof AccessDeniedException |
|
||||||
|
|
||||||
where: |
|
||||||
type << [SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE] |
|
||||||
} |
|
||||||
|
|
||||||
@Unroll |
|
||||||
def "intercept-message with invalid type and pattern - #type"(SimpMessageType type) { |
|
||||||
when: |
|
||||||
websocket { |
|
||||||
'intercept-message'(pattern : '/**', 'type': type.toString(), access:'permitAll') |
|
||||||
} |
|
||||||
then: |
|
||||||
thrown(BeanDefinitionParsingException) |
|
||||||
|
|
||||||
where: |
|
||||||
type << [SimpMessageType.CONNECT, SimpMessageType.CONNECT_ACK, SimpMessageType.DISCONNECT, SimpMessageType.DISCONNECT_ACK, SimpMessageType.HEARTBEAT, SimpMessageType.OTHER, SimpMessageType.UNSUBSCRIBE ] |
|
||||||
} |
|
||||||
|
|
||||||
def 'messages with no id automatically adds Authentication argument resolver'() { |
|
||||||
setup: |
|
||||||
def id = 'authenticationController' |
|
||||||
bean(id,MyController) |
|
||||||
bean('inPostProcessor',InboundExecutorPostProcessor) |
|
||||||
websocket { |
|
||||||
'intercept-message'(pattern:'/**',access:'permitAll') |
|
||||||
} |
|
||||||
|
|
||||||
when: 'message is sent to the authentication endpoint' |
|
||||||
clientInboundChannel.send(message('/authentication')) |
|
||||||
|
|
||||||
then: 'the AuthenticationPrincipal is resolved' |
|
||||||
def controller = appContext.getBean(id) |
|
||||||
controller.authenticationPrincipal == messageUser.name |
|
||||||
} |
|
||||||
|
|
||||||
def 'messages of type CONNECT use CsrfTokenHandshakeInterceptor'() { |
|
||||||
setup: |
|
||||||
def id = 'authenticationController' |
|
||||||
bean(id,MyController) |
|
||||||
bean('inPostProcessor',InboundExecutorPostProcessor) |
|
||||||
websocket { |
|
||||||
'intercept-message'(pattern:'/**',access:'permitAll') |
|
||||||
} |
|
||||||
|
|
||||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT) |
|
||||||
Message<?> message = message(headers,'/authentication') |
|
||||||
WebSocketHttpRequestHandler handler = appContext.getBean(WebSocketHttpRequestHandler) |
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest() |
|
||||||
String sessionAttr = "sessionAttr" |
|
||||||
request.getSession().setAttribute(sessionAttr,"sessionValue") |
|
||||||
|
|
||||||
CsrfToken token = new DefaultCsrfToken("header", "param", "token") |
|
||||||
request.setAttribute(CsrfToken.name, token) |
|
||||||
|
|
||||||
when: |
|
||||||
handler.handleRequest(request , new MockHttpServletResponse()) |
|
||||||
TestHandshakeHandler handshakeHandler = appContext.getBean(TestHandshakeHandler) |
|
||||||
|
|
||||||
then: 'CsrfToken is populated' |
|
||||||
handshakeHandler.attributes.get(CsrfToken.name) == token |
|
||||||
|
|
||||||
and: 'Explicitly listed HandshakeInterceptor are not overridden' |
|
||||||
handshakeHandler.attributes.get(sessionAttr) == request.getSession().getAttribute(sessionAttr) |
|
||||||
} |
|
||||||
|
|
||||||
def 'messages of type CONNECT use CsrfTokenHandshakeInterceptor with SockJS'() { |
|
||||||
setup: |
|
||||||
useSockJS = true |
|
||||||
def id = 'authenticationController' |
|
||||||
bean(id,MyController) |
|
||||||
bean('inPostProcessor',InboundExecutorPostProcessor) |
|
||||||
websocket { |
|
||||||
'intercept-message'(pattern:'/**',access:'permitAll') |
|
||||||
} |
|
||||||
|
|
||||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT) |
|
||||||
Message<?> message = message(headers,'/authentication') |
|
||||||
SockJsHttpRequestHandler handler = appContext.getBean(SockJsHttpRequestHandler) |
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest() |
|
||||||
String sessionAttr = "sessionAttr" |
|
||||||
request.getSession().setAttribute(sessionAttr,"sessionValue") |
|
||||||
|
|
||||||
CsrfToken token = new DefaultCsrfToken("header", "param", "token") |
|
||||||
request.setAttribute(CsrfToken.name, token) |
|
||||||
|
|
||||||
request.setMethod("GET") |
|
||||||
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/289/tpyx6mde/websocket") |
|
||||||
|
|
||||||
when: |
|
||||||
handler.handleRequest(request , new MockHttpServletResponse()) |
|
||||||
TestHandshakeHandler handshakeHandler = appContext.getBean(TestHandshakeHandler) |
|
||||||
|
|
||||||
then: 'CsrfToken is populated' |
|
||||||
handshakeHandler.attributes?.get(CsrfToken.name) == token |
|
||||||
|
|
||||||
and: 'Explicitly listed HandshakeInterceptor are not overridden' |
|
||||||
handshakeHandler.attributes?.get(sessionAttr) == request.getSession().getAttribute(sessionAttr) |
|
||||||
} |
|
||||||
|
|
||||||
def 'messages of type CONNECT require valid CsrfToken'() { |
|
||||||
setup: |
|
||||||
def id = 'authenticationController' |
|
||||||
bean(id,MyController) |
|
||||||
bean('inPostProcessor',InboundExecutorPostProcessor) |
|
||||||
websocket { |
|
||||||
'intercept-message'(pattern:'/**',access:'permitAll') |
|
||||||
} |
|
||||||
|
|
||||||
when: 'websocket of type CONNECTION is sent without CsrfTOken' |
|
||||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT) |
|
||||||
Message<?> message = message(headers,'/authentication') |
|
||||||
clientInboundChannel.send(message) |
|
||||||
|
|
||||||
then: 'CSRF Protection blocks the Message' |
|
||||||
MessageDeliveryException expected = thrown() |
|
||||||
expected.cause instanceof InvalidCsrfTokenException |
|
||||||
} |
|
||||||
|
|
||||||
def 'messages of type CONNECT disabled valid CsrfToken'() { |
|
||||||
setup: |
|
||||||
def id = 'authenticationController' |
|
||||||
bean(id,MyController) |
|
||||||
bean('inPostProcessor',InboundExecutorPostProcessor) |
|
||||||
websocket('same-origin-disabled':true) { |
|
||||||
'intercept-message'(pattern:'/**',access:'permitAll') |
|
||||||
} |
|
||||||
|
|
||||||
when: 'websocket of type CONNECTION is sent without CsrfTOken' |
|
||||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT) |
|
||||||
Message<?> message = message(headers,'/authentication') |
|
||||||
clientInboundChannel.send(message) |
|
||||||
|
|
||||||
then: 'CSRF Protection blocks the Message' |
|
||||||
noExceptionThrown() |
|
||||||
} |
|
||||||
|
|
||||||
def 'websocket with no id does not override customArgumentResolvers'() { |
|
||||||
setup: |
|
||||||
def id = 'authenticationController' |
|
||||||
bean(id,MyController) |
|
||||||
bean('inPostProcessor',InboundExecutorPostProcessor) |
|
||||||
bean('mcar', MyCustomArgumentResolver) |
|
||||||
xml.'websocket:message-broker' { |
|
||||||
'websocket:transport' {} |
|
||||||
'websocket:stomp-endpoint'(path:'/app') { |
|
||||||
'websocket:handshake-handler'(ref:'testHandler') {} |
|
||||||
} |
|
||||||
'websocket:simple-broker'(prefix:"/queue, /topic"){} |
|
||||||
'websocket:argument-resolvers' { |
|
||||||
'b:ref'(bean:'mcar') |
|
||||||
} |
|
||||||
} |
|
||||||
websocket { |
|
||||||
'intercept-message'(pattern:'/**',access:'permitAll') |
|
||||||
} |
|
||||||
|
|
||||||
when: 'websocket is sent to the myCustom endpoint' |
|
||||||
clientInboundChannel.send(message('/myCustom')) |
|
||||||
|
|
||||||
then: 'myCustomArgument is resolved' |
|
||||||
def controller = appContext.getBean(id) |
|
||||||
controller.myCustomArgument!= null |
|
||||||
} |
|
||||||
|
|
||||||
def 'websocket defaults pathMatcher'() { |
|
||||||
setup: |
|
||||||
bean('pathMatcher',AntPathMatcher.name,['.']) |
|
||||||
bean('testHandler', TestHandshakeHandler) |
|
||||||
xml.'websocket:message-broker'('path-matcher':'pathMatcher') { |
|
||||||
'websocket:transport' {} |
|
||||||
'websocket:stomp-endpoint'(path:'/app') { |
|
||||||
'websocket:handshake-handler'(ref:'testHandler') {} |
|
||||||
} |
|
||||||
'websocket:simple-broker'(prefix:"/queue, /topic"){} |
|
||||||
} |
|
||||||
xml.'websocket-message-broker' { |
|
||||||
'intercept-message'(pattern:'/denyAll.*',access:'denyAll') |
|
||||||
} |
|
||||||
createAppContext() |
|
||||||
|
|
||||||
when: 'sent to denyAll.a' |
|
||||||
appContext.getBean(SimpAnnotationMethodMessageHandler) |
|
||||||
clientInboundChannel.send(message('/denyAll.a')) |
|
||||||
|
|
||||||
then: 'access is denied' |
|
||||||
MessageDeliveryException expected = thrown() |
|
||||||
expected.cause instanceof AccessDeniedException |
|
||||||
|
|
||||||
when: 'sent to denyAll.a.b' |
|
||||||
clientInboundChannel.send(message('/denyAll.a.b')) |
|
||||||
|
|
||||||
then: 'access is allowed' |
|
||||||
noExceptionThrown() |
|
||||||
} |
|
||||||
|
|
||||||
def 'websocket with id does not integrate with clientInboundChannel'() { |
|
||||||
setup: |
|
||||||
websocket([id:'inCsi']) { |
|
||||||
'intercept-message'(pattern:'/**',access:'denyAll') |
|
||||||
} |
|
||||||
|
|
||||||
when: |
|
||||||
def success = clientInboundChannel.send(message('/denyAll')) |
|
||||||
|
|
||||||
then: |
|
||||||
success |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
def 'websocket with id can be explicitly integrated with clientInboundChannel'() { |
|
||||||
setup: 'websocket security explicitly setup' |
|
||||||
xml.'websocket:message-broker' { |
|
||||||
'websocket:transport' {} |
|
||||||
'websocket:stomp-endpoint'(path:'/app') { |
|
||||||
'websocket:sockjs' {} |
|
||||||
} |
|
||||||
'websocket:simple-broker'(prefix:"/queue, /topic"){} |
|
||||||
'websocket:client-inbound-channel' { |
|
||||||
'websocket:interceptors' { |
|
||||||
'b:bean'(class:'org.springframework.security.messaging.context.SecurityContextChannelInterceptor'){} |
|
||||||
'b:ref'(bean:'inCsi'){} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
xml.'websocket-message-broker'(id:'inCsi') { |
|
||||||
'intercept-message'(pattern:'/**',access:'denyAll') |
|
||||||
} |
|
||||||
createAppContext() |
|
||||||
|
|
||||||
when: |
|
||||||
clientInboundChannel.send(message('/denyAll')) |
|
||||||
|
|
||||||
then: |
|
||||||
def e = thrown(MessageDeliveryException) |
|
||||||
e.cause instanceof AccessDeniedException |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
def 'automatic integration with clientInboundChannel does not override exisiting websocket:interceptors'() { |
|
||||||
setup: |
|
||||||
mockBean(ChannelInterceptor,'mci') |
|
||||||
xml.'websocket:message-broker'('application-destination-prefix':'/app', |
|
||||||
'user-destination-prefix':'/user') { |
|
||||||
'websocket:transport' {} |
|
||||||
'websocket:stomp-endpoint'(path:'/foo') { |
|
||||||
'websocket:sockjs' {} |
|
||||||
} |
|
||||||
'websocket:simple-broker'(prefix:"/queue, /topic"){} |
|
||||||
'websocket:client-inbound-channel' { |
|
||||||
'websocket:interceptors' { |
|
||||||
'b:ref'(bean:'mci'){} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
xml.'websocket-message-broker' { |
|
||||||
'intercept-message'(pattern:'/denyAll',access:'denyAll') |
|
||||||
'intercept-message'(pattern:'/permitAll',access:'permitAll') |
|
||||||
} |
|
||||||
createAppContext() |
|
||||||
ChannelInterceptor mci = appContext.getBean('mci') |
|
||||||
when: |
|
||||||
Message<?> message = message('/permitAll') |
|
||||||
clientInboundChannel.send(message) |
|
||||||
|
|
||||||
then: |
|
||||||
verify(mci).preSend(message, clientInboundChannel) || true |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
def websocket(Map<String,Object> attrs=[:], Closure c) { |
|
||||||
bean('testHandler', TestHandshakeHandler) |
|
||||||
xml.'websocket:message-broker' { |
|
||||||
'websocket:transport' {} |
|
||||||
'websocket:stomp-endpoint'(path:'/app') { |
|
||||||
'websocket:handshake-handler'(ref:'testHandler') {} |
|
||||||
'websocket:handshake-interceptors' { |
|
||||||
'b:bean'('class':HttpSessionHandshakeInterceptor.name) {} |
|
||||||
} |
|
||||||
if(useSockJS) { |
|
||||||
'websocket:sockjs' {} |
|
||||||
} |
|
||||||
} |
|
||||||
'websocket:simple-broker'(prefix:"/queue, /topic"){} |
|
||||||
} |
|
||||||
xml.'websocket-message-broker'(attrs, c) |
|
||||||
createAppContext() |
|
||||||
} |
|
||||||
|
|
||||||
def 'custom expressions'() { |
|
||||||
setup: |
|
||||||
bean('expressionHandler', DenyRobMessageSecurityExpressionHandler) |
|
||||||
websocket { |
|
||||||
'expression-handler' (ref: 'expressionHandler') {} |
|
||||||
'intercept-message'(pattern:'/**',access:'denyRob()') |
|
||||||
} |
|
||||||
|
|
||||||
when: 'message is sent with user' |
|
||||||
clientInboundChannel.send(message('/message')) |
|
||||||
|
|
||||||
then: 'access is allowed to custom expression' |
|
||||||
noExceptionThrown() |
|
||||||
|
|
||||||
when: |
|
||||||
messageUser = new TestingAuthenticationToken('rob', 'pass', 'ROLE_USER') |
|
||||||
clientInboundChannel.send(message('/message')) |
|
||||||
|
|
||||||
then: |
|
||||||
def e = thrown(MessageDeliveryException) |
|
||||||
e.cause instanceof AccessDeniedException |
|
||||||
} |
|
||||||
|
|
||||||
def getClientInboundChannel() { |
|
||||||
appContext.getBean("clientInboundChannel") |
|
||||||
} |
|
||||||
|
|
||||||
def message(String destination, SimpMessageType type=SimpMessageType.MESSAGE) { |
|
||||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(type) |
|
||||||
message(headers, destination) |
|
||||||
} |
|
||||||
|
|
||||||
def message(SimpMessageHeaderAccessor headers, String destination) { |
|
||||||
headers.sessionId = '123' |
|
||||||
headers.sessionAttributes = [:] |
|
||||||
headers.destination = destination |
|
||||||
if(messageUser != null) { |
|
||||||
headers.user = messageUser |
|
||||||
} |
|
||||||
if(csrfToken != null) { |
|
||||||
headers.sessionAttributes[CsrfToken.name] = csrfToken |
|
||||||
} |
|
||||||
new GenericMessage<String>("hi",headers.messageHeaders) |
|
||||||
} |
|
||||||
|
|
||||||
@Controller |
|
||||||
static class MyController { |
|
||||||
String authenticationPrincipal |
|
||||||
MyCustomArgument myCustomArgument |
|
||||||
|
|
||||||
@MessageMapping('/authentication') |
|
||||||
public void authentication(@AuthenticationPrincipal String un) { |
|
||||||
this.authenticationPrincipal = un |
|
||||||
} |
|
||||||
|
|
||||||
@MessageMapping('/myCustom') |
|
||||||
public void myCustom(MyCustomArgument myCustomArgument) { |
|
||||||
this.myCustomArgument = myCustomArgument |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static class MyCustomArgument { |
|
||||||
MyCustomArgument(String notDefaultConstr) {} |
|
||||||
} |
|
||||||
|
|
||||||
static class MyCustomArgumentResolver implements HandlerMethodArgumentResolver { |
|
||||||
|
|
||||||
@Override |
|
||||||
boolean supportsParameter(MethodParameter parameter) { |
|
||||||
parameter.parameterType.isAssignableFrom(MyCustomArgument) |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
Object resolveArgument(MethodParameter parameter, Message<?> message) throws Exception { |
|
||||||
new MyCustomArgument("") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static class TestHandshakeHandler implements HandshakeHandler { |
|
||||||
Map<String, Object> attributes; |
|
||||||
|
|
||||||
boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws HandshakeFailureException { |
|
||||||
this.attributes = attributes |
|
||||||
if(wsHandler instanceof SockJsWebSocketHandler) { |
|
||||||
// work around SPR-12716 |
|
||||||
SockJsWebSocketHandler sockJs = (SockJsWebSocketHandler) wsHandler; |
|
||||||
this.attributes = sockJs.sockJsSession.attributes |
|
||||||
} |
|
||||||
true |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Changes the clientInboundChannel Executor to be synchronous |
|
||||||
*/ |
|
||||||
static class InboundExecutorPostProcessor implements BeanDefinitionRegistryPostProcessor { |
|
||||||
|
|
||||||
@Override |
|
||||||
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { |
|
||||||
BeanDefinition inbound = registry.getBeanDefinition("clientInboundChannel") |
|
||||||
inbound.getConstructorArgumentValues().addIndexedArgumentValue(0, new RootBeanDefinition(SyncTaskExecutor)); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static class DenyRobMessageSecurityExpressionHandler extends DefaultMessageSecurityExpressionHandler<Object> { |
|
||||||
@Override |
|
||||||
protected SecurityExpressionOperations createSecurityExpressionRoot( |
|
||||||
Authentication authentication, |
|
||||||
Message<Object> invocation) { |
|
||||||
return new MessageSecurityExpressionRoot(authentication, invocation) { |
|
||||||
public boolean denyRob() { |
|
||||||
Authentication auth = getAuthentication(); |
|
||||||
return auth != null && !"rob".equals(auth.getName()); |
|
||||||
} |
|
||||||
}; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -0,0 +1,547 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2018 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. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.security.config.websocket; |
||||||
|
|
||||||
|
import org.assertj.core.api.ThrowableAssert; |
||||||
|
import org.assertj.core.api.ThrowableAssert.ThrowingCallable; |
||||||
|
import org.junit.Rule; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.springframework.beans.BeansException; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.config.BeanDefinition; |
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; |
||||||
|
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; |
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry; |
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; |
||||||
|
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||||
|
import org.springframework.core.MethodParameter; |
||||||
|
import org.springframework.core.task.SyncTaskExecutor; |
||||||
|
import org.springframework.http.server.ServerHttpRequest; |
||||||
|
import org.springframework.messaging.Message; |
||||||
|
import org.springframework.messaging.MessageChannel; |
||||||
|
import org.springframework.messaging.handler.annotation.MessageMapping; |
||||||
|
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver; |
||||||
|
import org.springframework.messaging.simp.SimpMessageHeaderAccessor; |
||||||
|
import org.springframework.messaging.simp.SimpMessageType; |
||||||
|
import org.springframework.messaging.support.ChannelInterceptorAdapter; |
||||||
|
import org.springframework.messaging.support.GenericMessage; |
||||||
|
import org.springframework.security.access.AccessDeniedException; |
||||||
|
import org.springframework.security.access.expression.SecurityExpressionOperations; |
||||||
|
import org.springframework.security.config.test.SpringTestRule; |
||||||
|
import org.springframework.security.core.Authentication; |
||||||
|
import org.springframework.security.core.annotation.AuthenticationPrincipal; |
||||||
|
import org.springframework.security.core.context.SecurityContextHolder; |
||||||
|
import org.springframework.security.messaging.access.expression.DefaultMessageSecurityExpressionHandler; |
||||||
|
import org.springframework.security.messaging.access.expression.MessageSecurityExpressionRoot; |
||||||
|
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners; |
||||||
|
import org.springframework.security.test.context.support.WithMockUser; |
||||||
|
import org.springframework.security.web.csrf.CsrfToken; |
||||||
|
import org.springframework.security.web.csrf.DefaultCsrfToken; |
||||||
|
import org.springframework.security.web.csrf.InvalidCsrfTokenException; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
||||||
|
import org.springframework.test.web.servlet.MockMvc; |
||||||
|
import org.springframework.test.web.servlet.MvcResult; |
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders; |
||||||
|
import org.springframework.web.context.WebApplicationContext; |
||||||
|
import org.springframework.web.socket.WebSocketHandler; |
||||||
|
import org.springframework.web.socket.server.HandshakeFailureException; |
||||||
|
import org.springframework.web.socket.server.HandshakeHandler; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.*; |
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Rob Winch |
||||||
|
* @author Josh Cummings |
||||||
|
*/ |
||||||
|
@RunWith(SpringJUnit4ClassRunner.class) |
||||||
|
@SecurityTestExecutionListeners |
||||||
|
public class WebSocketMessageBrokerConfigTests { |
||||||
|
private static final String CONFIG_LOCATION_PREFIX = |
||||||
|
"classpath:org/springframework/security/config/websocket/WebSocketMessageBrokerConfigTests"; |
||||||
|
|
||||||
|
@Rule |
||||||
|
public final SpringTestRule spring = new SpringTestRule(); |
||||||
|
|
||||||
|
@Autowired(required = false) |
||||||
|
private MessageChannel clientInboundChannel; |
||||||
|
|
||||||
|
@Autowired(required = false) |
||||||
|
private MessageController messageController; |
||||||
|
|
||||||
|
@Autowired(required = false) |
||||||
|
private MessageWithArgumentController messageWithArgumentController; |
||||||
|
|
||||||
|
@Autowired(required = false) |
||||||
|
private TestHandshakeHandler testHandshakeHandler; |
||||||
|
|
||||||
|
private CsrfToken token = new DefaultCsrfToken("header", "param", "token"); |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenNoIdSpecifiedThenIntegratesWithClientInboundChannel() { |
||||||
|
this.spring.configLocations(xml("NoIdConfig")).autowire(); |
||||||
|
|
||||||
|
this.clientInboundChannel.send(message("/permitAll")); |
||||||
|
|
||||||
|
assertThatThrownBy(() -> this.clientInboundChannel.send(message("/denyAll"))) |
||||||
|
.hasCauseInstanceOf(AccessDeniedException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenAnonymousMessageWithConnectMessageTypeThenPermitted() { |
||||||
|
this.spring.configLocations(xml("NoIdConfig")).autowire(); |
||||||
|
|
||||||
|
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT); |
||||||
|
headers.setNativeHeader(this.token.getHeaderName(), this.token.getToken()); |
||||||
|
|
||||||
|
assertThatCode(() -> this.clientInboundChannel.send(message("/permitAll", headers))) |
||||||
|
.doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenAnonymousMessageWithConnectAckMessageTypeThenPermitted() { |
||||||
|
this.spring.configLocations(xml("NoIdConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/permitAll", SimpMessageType.CONNECT_ACK); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenAnonymousMessageWithDisconnectMessageTypeThenPermitted() { |
||||||
|
this.spring.configLocations(xml("NoIdConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/permitAll", SimpMessageType.DISCONNECT); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenAnonymousMessageWithDisconnectAckMessageTypeThenPermitted() { |
||||||
|
this.spring.configLocations(xml("NoIdConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/permitAll", SimpMessageType.DISCONNECT_ACK); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenAnonymousMessageWithHeartbeatMessageTypeThenPermitted() { |
||||||
|
this.spring.configLocations(xml("NoIdConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/permitAll", SimpMessageType.HEARTBEAT); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenAnonymousMessageWithMessageMessageTypeThenPermitted() { |
||||||
|
this.spring.configLocations(xml("NoIdConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/permitAll", SimpMessageType.MESSAGE); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenAnonymousMessageWithOtherMessageTypeThenPermitted() { |
||||||
|
this.spring.configLocations(xml("NoIdConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/permitAll", SimpMessageType.OTHER); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenAnonymousMessageWithSubscribeMessageTypeThenPermitted() { |
||||||
|
this.spring.configLocations(xml("NoIdConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/permitAll", SimpMessageType.SUBSCRIBE); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenAnonymousMessageWithUnsubscribeMessageTypeThenPermitted() { |
||||||
|
this.spring.configLocations(xml("NoIdConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/permitAll", SimpMessageType.UNSUBSCRIBE); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenConnectWithoutCsrfTokenThenDenied() { |
||||||
|
this.spring.configLocations(xml("SyncConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/message", SimpMessageType.CONNECT); |
||||||
|
|
||||||
|
assertThatThrownBy(send(message)).hasCauseInstanceOf(InvalidCsrfTokenException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenConnectWithSameOriginDisabledThenCsrfTokenNotRequired() { |
||||||
|
this.spring.configLocations(xml("SyncSameOriginDisabledConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/message", SimpMessageType.CONNECT); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenInterceptWiredForMessageTypeThenDeniesOnTypeMismatch() { |
||||||
|
this.spring.configLocations(xml("MessageInterceptTypeConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/permitAll", SimpMessageType.MESSAGE); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
|
||||||
|
message = message("/permitAll", SimpMessageType.UNSUBSCRIBE); |
||||||
|
|
||||||
|
assertThatThrownBy(send(message)).hasCauseInstanceOf(AccessDeniedException.class); |
||||||
|
|
||||||
|
message = message("/anyOther", SimpMessageType.MESSAGE); |
||||||
|
|
||||||
|
assertThatThrownBy(send(message)).hasCauseInstanceOf(AccessDeniedException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenInterceptWiredForSubscribeTypeThenDeniesOnTypeMismatch() { |
||||||
|
this.spring.configLocations(xml("SubscribeInterceptTypeConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/permitAll", SimpMessageType.SUBSCRIBE); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
|
||||||
|
message = message("/permitAll", SimpMessageType.UNSUBSCRIBE); |
||||||
|
|
||||||
|
assertThatThrownBy(send(message)).hasCauseInstanceOf(AccessDeniedException.class); |
||||||
|
|
||||||
|
message = message("/anyOther", SimpMessageType.SUBSCRIBE); |
||||||
|
|
||||||
|
assertThatThrownBy(send(message)).hasCauseInstanceOf(AccessDeniedException.class); |
||||||
|
} |
||||||
|
|
||||||
|
// -- invalid intercept types -- //
|
||||||
|
|
||||||
|
@Test |
||||||
|
public void configureWhenUsingConnectMessageTypeThenAutowireFails() { |
||||||
|
ThrowingCallable bad = () -> |
||||||
|
this.spring.configLocations(xml("ConnectInterceptTypeConfig")).autowire(); |
||||||
|
|
||||||
|
assertThatThrownBy(bad).isInstanceOf(BeanDefinitionParsingException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void configureWhenUsingConnectAckMessageTypeThenAutowireFails() { |
||||||
|
ThrowingCallable bad = () -> |
||||||
|
this.spring.configLocations(xml("ConnectAckInterceptTypeConfig")).autowire(); |
||||||
|
|
||||||
|
assertThatThrownBy(bad).isInstanceOf(BeanDefinitionParsingException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void configureWhenUsingDisconnectMessageTypeThenAutowireFails() { |
||||||
|
ThrowingCallable bad = () -> |
||||||
|
this.spring.configLocations(xml("DisconnectInterceptTypeConfig")).autowire(); |
||||||
|
|
||||||
|
assertThatThrownBy(bad).isInstanceOf(BeanDefinitionParsingException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void configureWhenUsingDisconnectAckMessageTypeThenAutowireFails() { |
||||||
|
ThrowingCallable bad = () -> |
||||||
|
this.spring.configLocations(xml("DisconnectAckInterceptTypeConfig")).autowire(); |
||||||
|
|
||||||
|
assertThatThrownBy(bad).isInstanceOf(BeanDefinitionParsingException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void configureWhenUsingHeartbeatMessageTypeThenAutowireFails() { |
||||||
|
ThrowingCallable bad = () -> |
||||||
|
this.spring.configLocations(xml("HeartbeatInterceptTypeConfig")).autowire(); |
||||||
|
|
||||||
|
assertThatThrownBy(bad).isInstanceOf(BeanDefinitionParsingException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void configureWhenUsingOtherMessageTypeThenAutowireFails() { |
||||||
|
ThrowingCallable bad = () -> |
||||||
|
this.spring.configLocations(xml("OtherInterceptTypeConfig")).autowire(); |
||||||
|
|
||||||
|
assertThatThrownBy(bad).isInstanceOf(BeanDefinitionParsingException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void configureWhenUsingUnsubscribeMessageTypeThenAutowireFails() { |
||||||
|
ThrowingCallable bad = () -> |
||||||
|
this.spring.configLocations(xml("UnsubscribeInterceptTypeConfig")).autowire(); |
||||||
|
|
||||||
|
assertThatThrownBy(bad).isInstanceOf(BeanDefinitionParsingException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenNoIdMessageThenAuthenticationPrincipalResolved() throws Exception { |
||||||
|
this.spring.configLocations(xml("SyncConfig")).autowire(); |
||||||
|
|
||||||
|
this.clientInboundChannel.send(message("/message")); |
||||||
|
|
||||||
|
assertThat(this.messageController.username).isEqualTo("anonymous"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void requestWhenConnectMessageThenUsesCsrfTokenHandshakeInterceptor() throws Exception { |
||||||
|
this.spring.configLocations(xml("SyncConfig")).autowire(); |
||||||
|
|
||||||
|
WebApplicationContext context = (WebApplicationContext) this.spring.getContext(); |
||||||
|
MockMvc mvc = MockMvcBuilders.webAppContextSetup(context).build(); |
||||||
|
|
||||||
|
String csrfAttributeName = CsrfToken.class.getName(); |
||||||
|
String customAttributeName = this.getClass().getName(); |
||||||
|
|
||||||
|
MvcResult result = mvc.perform(get("/app") |
||||||
|
.requestAttr(csrfAttributeName, this.token) |
||||||
|
.sessionAttr(customAttributeName, "attributeValue")) |
||||||
|
.andReturn(); |
||||||
|
|
||||||
|
CsrfToken handshakeToken = (CsrfToken) this.testHandshakeHandler.attributes.get(csrfAttributeName); |
||||||
|
String handshakeValue = (String) this.testHandshakeHandler.attributes.get(customAttributeName); |
||||||
|
String sessionValue = (String) result.getRequest().getSession().getAttribute(customAttributeName); |
||||||
|
|
||||||
|
assertThat(handshakeToken).isEqualTo(this.token) |
||||||
|
.withFailMessage("CsrfToken is populated"); |
||||||
|
|
||||||
|
assertThat(handshakeValue).isEqualTo(sessionValue) |
||||||
|
.withFailMessage("Explicitly listed session variables are not overridden"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void requestWhenConnectMessageAndUsingSockJsThenUsesCsrfTokenHandshakeInterceptor() throws Exception { |
||||||
|
this.spring.configLocations(xml("SyncSockJsConfig")).autowire(); |
||||||
|
|
||||||
|
WebApplicationContext context = (WebApplicationContext) this.spring.getContext(); |
||||||
|
MockMvc mvc = MockMvcBuilders.webAppContextSetup(context).build(); |
||||||
|
|
||||||
|
String csrfAttributeName = CsrfToken.class.getName(); |
||||||
|
String customAttributeName = this.getClass().getName(); |
||||||
|
|
||||||
|
MvcResult result = mvc.perform(get("/app/289/tpyx6mde/websocket") |
||||||
|
.requestAttr(csrfAttributeName, this.token) |
||||||
|
.sessionAttr(customAttributeName, "attributeValue")) |
||||||
|
.andReturn(); |
||||||
|
|
||||||
|
CsrfToken handshakeToken = (CsrfToken) this.testHandshakeHandler.attributes.get(csrfAttributeName); |
||||||
|
String handshakeValue = (String) this.testHandshakeHandler.attributes.get(customAttributeName); |
||||||
|
String sessionValue = (String) result.getRequest().getSession().getAttribute(customAttributeName); |
||||||
|
|
||||||
|
assertThat(handshakeToken).isEqualTo(this.token) |
||||||
|
.withFailMessage("CsrfToken is populated"); |
||||||
|
|
||||||
|
assertThat(handshakeValue).isEqualTo(sessionValue) |
||||||
|
.withFailMessage("Explicitly listed session variables are not overridden"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenNoIdSpecifiedThenCustomArgumentResolversAreNotOverridden() { |
||||||
|
this.spring.configLocations(xml("SyncCustomArgumentResolverConfig")).autowire(); |
||||||
|
|
||||||
|
this.clientInboundChannel.send(message("/message-with-argument")); |
||||||
|
|
||||||
|
assertThat(this.messageWithArgumentController.messageArgument).isNotNull(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenUsingCustomPathMatcherThenSecurityAppliesIt() { |
||||||
|
this.spring.configLocations(xml("CustomPathMatcherConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/denyAll.a"); |
||||||
|
|
||||||
|
assertThatThrownBy(send(message)).hasCauseInstanceOf(AccessDeniedException.class); |
||||||
|
|
||||||
|
message = message("/denyAll.a.b"); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenIdSpecifiedThenSecurityDoesNotIntegrateWithClientInboundChannel() { |
||||||
|
this.spring.configLocations(xml("IdConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/denyAll"); |
||||||
|
|
||||||
|
assertThatCode(send(message)).doesNotThrowAnyException(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@WithMockUser |
||||||
|
public void sendWhenIdSpecifiedAndExplicitlyIntegratedWhenBrokerUsesClientInboundChannel() { |
||||||
|
this.spring.configLocations(xml("IdIntegratedConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/denyAll"); |
||||||
|
|
||||||
|
assertThatThrownBy(send(message)).hasCauseInstanceOf(AccessDeniedException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void sendWhenNoIdSpecifiedThenSecurityDoesntOverrideCustomInterceptors() { |
||||||
|
this.spring.configLocations(xml("CustomInterceptorConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/throwAll"); |
||||||
|
|
||||||
|
assertThatThrownBy(send(message)).hasCauseInstanceOf(UnsupportedOperationException.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@WithMockUser(username = "nile") |
||||||
|
public void sendWhenCustomExpressionHandlerThenAuthorizesAccordingly() { |
||||||
|
this.spring.configLocations(xml("CustomExpressionHandlerConfig")).autowire(); |
||||||
|
|
||||||
|
Message<?> message = message("/denyNile"); |
||||||
|
|
||||||
|
assertThatThrownBy(send(message)).hasCauseInstanceOf(AccessDeniedException.class); |
||||||
|
} |
||||||
|
|
||||||
|
private String xml(String configName) { |
||||||
|
return CONFIG_LOCATION_PREFIX + "-" + configName + ".xml"; |
||||||
|
} |
||||||
|
|
||||||
|
private ThrowableAssert.ThrowingCallable send(Message<?> message) { |
||||||
|
return () -> this.clientInboundChannel.send(message); |
||||||
|
} |
||||||
|
|
||||||
|
private Message<?> message(String destination) { |
||||||
|
return message(destination, SimpMessageType.MESSAGE); |
||||||
|
} |
||||||
|
|
||||||
|
private Message<?> message(String destination, SimpMessageType type) { |
||||||
|
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(type); |
||||||
|
return message(destination, headers); |
||||||
|
} |
||||||
|
|
||||||
|
private Message<?> message(String destination, SimpMessageHeaderAccessor headers) { |
||||||
|
headers.setSessionId("123"); |
||||||
|
headers.setSessionAttributes(new HashMap<>()); |
||||||
|
headers.setDestination(destination); |
||||||
|
|
||||||
|
if (SecurityContextHolder.getContext().getAuthentication() != null) { |
||||||
|
headers.setUser(SecurityContextHolder.getContext().getAuthentication()); |
||||||
|
} |
||||||
|
|
||||||
|
headers.getSessionAttributes().put(CsrfToken.class.getName(), this.token); |
||||||
|
|
||||||
|
return new GenericMessage<>("hi", headers.getMessageHeaders()); |
||||||
|
} |
||||||
|
|
||||||
|
@Controller |
||||||
|
static class MessageController { |
||||||
|
String username; |
||||||
|
|
||||||
|
@MessageMapping("/message") |
||||||
|
public void authentication(@AuthenticationPrincipal String username) { |
||||||
|
this.username = username; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Controller |
||||||
|
static class MessageWithArgumentController { |
||||||
|
MessageArgument messageArgument; |
||||||
|
|
||||||
|
@MessageMapping("/message-with-argument") |
||||||
|
public void myCustom(MessageArgument messageArgument) { |
||||||
|
this.messageArgument = messageArgument; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
static class MessageArgument { |
||||||
|
MessageArgument(String notDefaultConstructor) { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static class MessageArgumentResolver implements HandlerMethodArgumentResolver { |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean supportsParameter(MethodParameter parameter) { |
||||||
|
return parameter.getParameterType().isAssignableFrom(MessageArgument.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object resolveArgument(MethodParameter parameter, Message<?> message) throws Exception { |
||||||
|
return new MessageArgument(""); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static class TestHandshakeHandler implements HandshakeHandler { |
||||||
|
Map<String, Object> attributes; |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean doHandshake( |
||||||
|
ServerHttpRequest request, |
||||||
|
org.springframework.http.server.ServerHttpResponse response, |
||||||
|
WebSocketHandler wsHandler, |
||||||
|
Map<String, Object> attributes) throws HandshakeFailureException { |
||||||
|
|
||||||
|
this.attributes = attributes; |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static class InboundExecutorPostProcessor implements BeanDefinitionRegistryPostProcessor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { |
||||||
|
BeanDefinition inbound = registry.getBeanDefinition("clientInboundChannel"); |
||||||
|
inbound.getConstructorArgumentValues() |
||||||
|
.addIndexedArgumentValue(0, new RootBeanDefinition(SyncTaskExecutor.class)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static class ExceptingInterceptor extends ChannelInterceptorAdapter { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Message<?> preSend(Message<?> message, MessageChannel channel) { |
||||||
|
throw new UnsupportedOperationException("no"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static class DenyNileMessageSecurityExpressionHandler |
||||||
|
extends DefaultMessageSecurityExpressionHandler<Object> { |
||||||
|
|
||||||
|
@Override |
||||||
|
protected SecurityExpressionOperations createSecurityExpressionRoot( |
||||||
|
Authentication authentication, |
||||||
|
Message<Object> invocation) { |
||||||
|
|
||||||
|
return new MessageSecurityExpressionRoot(authentication, invocation) { |
||||||
|
public boolean denyNile() { |
||||||
|
Authentication auth = getAuthentication(); |
||||||
|
return auth != null && !"nile".equals(auth.getName()); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" type="CONNECT_ACK" access="permitAll"/> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" type="CONNECT" access="permitAll"/> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,33 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<b:bean name="expressionHandler" class="org.springframework.security.config.websocket.WebSocketMessageBrokerConfigTests.DenyNileMessageSecurityExpressionHandler"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<expression-handler ref="expressionHandler"/> |
||||||
|
<intercept-message pattern="/**" access="denyNile()"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,45 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:websocket="http://www.springframework.org/schema/websocket" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd |
||||||
|
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> |
||||||
|
|
||||||
|
<websocket:message-broker application-destination-prefix="/app" user-destination-prefix="/user"> |
||||||
|
<websocket:transport/> |
||||||
|
<websocket:stomp-endpoint path="/foo"> |
||||||
|
<websocket:sockjs/> |
||||||
|
</websocket:stomp-endpoint> |
||||||
|
<websocket:simple-broker prefix="/queue, /topic"/> |
||||||
|
<websocket:client-inbound-channel> |
||||||
|
<websocket:interceptors> |
||||||
|
<b:ref bean="eci"/> |
||||||
|
</websocket:interceptors> |
||||||
|
</websocket:client-inbound-channel> |
||||||
|
</websocket:message-broker> |
||||||
|
|
||||||
|
<b:bean name="eci" class="org.springframework.security.config.websocket.WebSocketMessageBrokerConfigTests.ExceptingInterceptor"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" access="permitAll"/> |
||||||
|
<intercept-message pattern="/denyAll" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,46 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:websocket="http://www.springframework.org/schema/websocket" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd |
||||||
|
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
|
||||||
|
<websocket:message-broker path-matcher="pathMatcher"> |
||||||
|
<websocket:transport/> |
||||||
|
<websocket:stomp-endpoint path="/app"> |
||||||
|
<websocket:handshake-handler ref="testHandler"/> |
||||||
|
</websocket:stomp-endpoint> |
||||||
|
|
||||||
|
<websocket:simple-broker prefix="/queue, /topic"/> |
||||||
|
</websocket:message-broker> |
||||||
|
|
||||||
|
<b:bean name="pathMatcher" class="org.springframework.util.AntPathMatcher"> |
||||||
|
<b:constructor-arg value="."/> |
||||||
|
</b:bean> |
||||||
|
|
||||||
|
<b:bean name="testHandler" class="org.springframework.security.config.websocket.WebSocketMessageBrokerConfigTests.TestHandshakeHandler"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/denyAll.*" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" type="DISCONNECT_ACK" access="permitAll"/> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" type="HEARTBEAT" access="permitAll"/> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" type="HEARTBEAT" access="permitAll"/> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker id="inCsi"> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:websocket="http://www.springframework.org/schema/websocket" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd |
||||||
|
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> |
||||||
|
|
||||||
|
<websocket:message-broker> |
||||||
|
<websocket:transport/> |
||||||
|
<websocket:stomp-endpoint path="/app"> |
||||||
|
<websocket:sockjs/> |
||||||
|
</websocket:stomp-endpoint> |
||||||
|
<websocket:simple-broker prefix="/queue, /topic"/> |
||||||
|
<websocket:client-inbound-channel> |
||||||
|
<websocket:interceptors> |
||||||
|
<b:ref bean="inCsi"/> |
||||||
|
</websocket:interceptors> |
||||||
|
</websocket:client-inbound-channel> |
||||||
|
</websocket:message-broker> |
||||||
|
|
||||||
|
<websocket-message-broker id="inCsi"> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" type="MESSAGE" access="permitAll"/> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" access="permitAll"/> |
||||||
|
<intercept-message pattern="/denyAll" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" type="OTHER" access="permitAll"/> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" type="SUBSCRIBE" access="permitAll"/> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/sync.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/**" access="permitAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,50 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:websocket="http://www.springframework.org/schema/websocket" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd |
||||||
|
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/sync.xml"/> |
||||||
|
|
||||||
|
<websocket:message-broker> |
||||||
|
<websocket:transport/> |
||||||
|
<websocket:stomp-endpoint path="/app"> |
||||||
|
<websocket:handshake-handler ref="testHandler"/> |
||||||
|
<websocket:handshake-interceptors> |
||||||
|
<b:bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/> |
||||||
|
</websocket:handshake-interceptors> |
||||||
|
</websocket:stomp-endpoint> |
||||||
|
|
||||||
|
<websocket:simple-broker prefix="/queue, /topic"/> |
||||||
|
<websocket:argument-resolvers> |
||||||
|
<b:ref bean="messageArgumentResolver"/> |
||||||
|
</websocket:argument-resolvers> |
||||||
|
</websocket:message-broker> |
||||||
|
|
||||||
|
<b:bean name="testHandler" class="org.springframework.security.config.websocket.WebSocketMessageBrokerConfigTests.TestHandshakeHandler"/> |
||||||
|
<b:bean name="messageArgumentResolver" class="org.springframework.security.config.websocket.WebSocketMessageBrokerConfigTests.MessageArgumentResolver"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/**" access="permitAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/sync.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker same-origin-disabled="true"> |
||||||
|
<intercept-message pattern="/**" access="permitAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/sync.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket-sockjs.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/**" access="permitAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/security" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd |
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/controllers.xml"/> |
||||||
|
<b:import resource="classpath:org/springframework/security/config/websocket/websocket.xml"/> |
||||||
|
|
||||||
|
<websocket-message-broker> |
||||||
|
<intercept-message pattern="/permitAll" type="UNSUBSCRIBE" access="permitAll"/> |
||||||
|
<intercept-message pattern="/**" access="denyAll"/> |
||||||
|
</websocket-message-broker> |
||||||
|
|
||||||
|
</b:beans> |
||||||
@ -0,0 +1,24 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/beans" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<bean class="org.springframework.security.config.websocket.WebSocketMessageBrokerConfigTests.MessageController"/> |
||||||
|
<bean class="org.springframework.security.config.websocket.WebSocketMessageBrokerConfigTests.MessageWithArgumentController"/> |
||||||
|
|
||||||
|
</beans> |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/beans" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||||
|
|
||||||
|
<bean class="org.springframework.security.config.websocket.WebSocketMessageBrokerConfigTests.InboundExecutorPostProcessor"/> |
||||||
|
</beans> |
||||||
@ -0,0 +1,37 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/websocket" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd |
||||||
|
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> |
||||||
|
|
||||||
|
<message-broker> |
||||||
|
<transport/> |
||||||
|
<stomp-endpoint path="/app"> |
||||||
|
<handshake-handler ref="testHandler"/> |
||||||
|
<handshake-interceptors> |
||||||
|
<b:bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/> |
||||||
|
</handshake-interceptors> |
||||||
|
<sockjs/> |
||||||
|
</stomp-endpoint> |
||||||
|
|
||||||
|
<simple-broker prefix="/queue, /topic"/> |
||||||
|
</message-broker> |
||||||
|
|
||||||
|
<b:bean name="testHandler" class="org.springframework.security.config.websocket.WebSocketMessageBrokerConfigTests.TestHandshakeHandler"/> |
||||||
|
</b:beans> |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2002-2018 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. |
||||||
|
~ You may obtain a copy of the License at |
||||||
|
~ |
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
~ |
||||||
|
~ Unless required by applicable law or agreed to in writing, software |
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
~ See the License for the specific language governing permissions and |
||||||
|
~ limitations under the License. |
||||||
|
--> |
||||||
|
<b:beans xmlns:b="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns="http://www.springframework.org/schema/websocket" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd |
||||||
|
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> |
||||||
|
|
||||||
|
<message-broker> |
||||||
|
<transport/> |
||||||
|
<stomp-endpoint path="/app"> |
||||||
|
<handshake-handler ref="testHandler"/> |
||||||
|
<handshake-interceptors> |
||||||
|
<b:bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/> |
||||||
|
</handshake-interceptors> |
||||||
|
</stomp-endpoint> |
||||||
|
|
||||||
|
<simple-broker prefix="/queue, /topic"/> |
||||||
|
</message-broker> |
||||||
|
|
||||||
|
<b:bean name="testHandler" class="org.springframework.security.config.websocket.WebSocketMessageBrokerConfigTests.TestHandshakeHandler"/> |
||||||
|
</b:beans> |
||||||
Loading…
Reference in new issue