Я следовал следующему руководству: Использование WebSocket для создания интерактивного веб-приложения
Все работает, как описано, и приложение выглядит нормально.У меня просто хороший контроллер:
@Controller
public class GreetingController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
Thread.sleep(1000); // simulated delay
return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
}
}
И немного конфигурации.
Теперь я хочу добавить безопасность для этого простого приложения.Я потратил время на поиск примера, но не смог его найти.
Обычно я нашел учебное пособие:
Предварительный просмотр поддержки Spring Security WebSocket
Но похоже, что этот пример относится только к весне 4, а не к весне 5. И я не понимаю, где я должен предоставить учетные данные и так далее.Описание недостаточно подробное, чтобы применить его для моего примера.
Еще один учебник, который я нашел: Аутентификация и авторизация Websocket в Spring Ask
Выглядит более понятно, ноЯ не уверен, что это лучшее решение на данный момент.
Можете ли вы посоветовать самый простой способ настройки безопасности Spring для моего приложения?
PS Также у меня естьнашел не тот же, но знакомый вопрос Как защитить приложение веб-сокета [Spring boot + STOMP] , но на данный момент нет ответов.
ОБНОВЛЕНИЕ для locus2k
Теперь у меня есть следующая конфигурация:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
private static String[] authorities = new String[]{
"VIEW_SCRIPT_TAB", "VIEW_CREDS_TAB"
};
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry
.addEndpoint("/gs-guide-websocket")
.addInterceptors(new HandshakeInterceptor() {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
System.out.println("Handshake interceptor beforeHandshake");
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, @Nullable Exception exception) {
System.out.println("Handshake interceptor after");
}
})
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry message) {
message
.nullDestMatcher().permitAll()
.simpDestMatchers("/app/**").hasAnyAuthority(authorities)
.simpSubscribeDestMatchers("/topic/**").permitAll()
.anyMessage().denyAll();
}
}
Бит, когда я запускаю приложение, я вижу трассировку стека:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'stompWebSocketHandlerMapping' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'stompWebSocketHandlerMapping' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'subProtocolWebSocketHandler' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.socket.WebSocketHandler]: Factory method 'subProtocolWebSocketHandler' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientInboundChannel' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.messaging.support.AbstractSubscribableChannel]: Factory method 'clientInboundChannel' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientInboundChannelExecutor' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor]: Factory method 'clientInboundChannelExecutor' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inboundChannelSecurity' defined in class path resource [com/my/ws/example/ws_example/hello/WebSocketConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor]: Factory method 'inboundChannelSecurity' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inboundMessageSecurityMetadataSource' defined in class path resource [com/my/ws/example/ws_example/hello/WebSocketConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource]: Factory method 'inboundMessageSecurityMetadataSource' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory.createExpressionMessageMetadataSource(Ljava/util/LinkedHashMap;Lorg/springframework/security/access/expression/SecurityExpressionHandler;)Lorg/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource;
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
....
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'stompWebSocketHandlerMapping' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'subProtocolWebSocketHandler' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.socket.WebSocketHandler]: Factory method 'subProtocolWebSocketHandler' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientInboundChannel' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.messaging.support.AbstractSubscribableChannel]: Factory method 'clientInboundChannel' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientInboundChannelExecutor' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor]: Factory method 'clientInboundChannelExecutor' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inboundChannelSecurity' defined in class path resource [com/my/ws/example/ws_example/hello/WebSocketConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor]: Factory method 'inboundChannelSecurity' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inboundMessageSecurityMetadataSource' defined in class path resource [com/my/ws/example/ws_example/hello/WebSocketConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource]: Factory method 'inboundMessageSecurityMetadataSource' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory.createExpressionMessageMetadataSource(Ljava/util/LinkedHashMap;Lorg/springframework/security/access/expression/SecurityExpressionHandler;)Lorg/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource;
... 18 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'subProtocolWebSocketHandler' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.socket.WebSocketHandler]: Factory method 'subProtocolWebSocketHandler' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientInboundChannel' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.messaging.support.AbstractSubscribableChannel]: Factory method 'clientInboundChannel' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientInboundChannelExecutor' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor]: Factory method 'clientInboundChannelExecutor' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inboundChannelSecurity' defined in class path resource [com/my/ws/example/ws_example/hello/WebSocketConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor]: Factory method 'inboundChannelSecurity' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inboundMessageSecurityMetadataSource' defined in class path resource [com/my/ws/example/ws_example/hello/WebSocketConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource]: Factory method 'inboundMessageSecurityMetadataSource' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory.createExpressionMessageMetadataSource(Ljava/util/LinkedHashMap;Lorg/springframework/security/access/expression/SecurityExpressionHandler;)Lorg/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource;
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 19 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.socket.WebSocketHandler]: Factory method 'subProtocolWebSocketHandler' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientInboundChannel' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.messaging.support.AbstractSubscribableChannel]: Factory method 'clientInboundChannel' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientInboundChannelExecutor' defined in class path resource [org/springframework/web/socket/config/annotation/DelegatingWebSocketMessageBrokerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor]: Factory method 'clientInboundChannelExecutor' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inboundChannelSecurity' defined in class path resource [com/my/ws/example/ws_example/hello/WebSocketConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor]: Factory method 'inboundChannelSecurity' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inboundMessageSecurityMetadataSource' defined in class path resource [com/my/ws/example/ws_example/hello/WebSocketConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource]: Factory method 'inboundMessageSecurityMetadataSource' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory.createExpressionMessageMetadataSource(Ljava/util/LinkedHashMap;Lorg/springframework/security/access/expression/SecurityExpressionHandler;)Lorg/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource;
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 41 common frames omitted
....
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor]: Factory method 'inboundChannelSecurity' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inboundMessageSecurityMetadataSource' defined in class path resource [com/my/ws/example/ws_example/hello/WebSocketConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource]: Factory method 'inboundMessageSecurityMetadataSource' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory.createExpressionMessageMetadataSource(Ljava/util/LinkedHashMap;Lorg/springframework/security/access/expression/SecurityExpressionHandler;)Lorg/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource;
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 113 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inboundMessageSecurityMetadataSource' defined in class path resource [com/my/ws/example/ws_example/hello/WebSocketConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource]: Factory method 'inboundMessageSecurityMetadataSource' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory.createExpressionMessageMetadataSource(Ljava/util/LinkedHashMap;Lorg/springframework/security/access/expression/SecurityExpressionHandler;)Lorg/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource;
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 114 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource]: Factory method 'inboundMessageSecurityMetadataSource' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory.createExpressionMessageMetadataSource(Ljava/util/LinkedHashMap;Lorg/springframework/security/access/expression/SecurityExpressionHandler;)Lorg/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource;
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 136 common frames omitted
Caused by: java.lang.NoSuchMethodError: org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory.createExpressionMessageMetadataSource(Ljava/util/LinkedHashMap;Lorg/springframework/security/access/expression/SecurityExpressionHandler;)Lorg/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource;
at org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry.createMetadataSource(MessageSecurityMetadataSourceRegistry.java:242) ~[spring-security-config-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.security.config.annotation.web.socket.AbstractSecurityWebSocketMessageBrokerConfigurer$WebSocketMessageSecurityMetadataSourceRegistry.createMetadataSource(AbstractSecurityWebSocketMessageBrokerConfigurer.java:193) ~[spring-security-config-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.security.config.annotation.web.socket.AbstractSecurityWebSocketMessageBrokerConfigurer.inboundMessageSecurityMetadataSource(AbstractSecurityWebSocketMessageBrokerConfigurer.java:179) ~[spring-security-config-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at com.my.ws.example.ws_example.hello.WebSocketConfig$$EnhancerBySpringCGLIB$$1ebc3c92.CGLIB$inboundMessageSecurityMetadataSource$6(<generated>) ~[classes/:na]
at com.my.ws.example.ws_example.hello.WebSocketConfig$$EnhancerBySpringCGLIB$$1ebc3c92$$FastClassBySpringCGLIB$$6d713310.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at com.my.ws.example.ws_example.hello.WebSocketConfig$$EnhancerBySpringCGLIB$$1ebc3c92.inboundMessageSecurityMetadataSource(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_111]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 137 common frames omitted