Как добавить безопасность для весны 5 веб-сокетов - PullRequest
0 голосов
/ 24 апреля 2018

Я следовал следующему руководству: Использование 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

Ответы [ 2 ]

0 голосов
/ 28 апреля 2018

Предоставлена ​​трассировка стека, связанная с несовместимыми версиями библиотеки.

Работает, если использовать правильные зависимости. Например:

compile ('org.springframework.security:spring-security-messaging:5.0.4.RELEASE')
compile ('org.springframework.security:spring-security-web: 5.0.4.RELEASE')
0 голосов
/ 24 апреля 2018

Связанные вами сообщения работают и для веб-сокетов Spring 5 и являются простейшим решением для расширения AbstractSecurityWebSocketMessageBrokerConfigurer

, например:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

  @Override
  public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableSimpleBroker("/topic");
    config.setApplicationDestinationPrefixes("/app");
  }

  @Override
  public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/stomp")
      .setAllowedOrigins("*")
      .withSockJS();
  }

  @Override
  protected void configureInbound(MessageSecurityMetadataSourceRegistry message) {
    message
      .nullDestMatcher().permitAll()
      .simpDestMatchers("/app/**").hasAnyAuthority(authorities)
      .simpSubscribeDestMatchers("/topic/ + "**").permitAll()
      .anyMessage().denyAll();
   }

   @Override
   protected boolean sameOriginDisabled() {
     return true;
   }    
}

Проверка безопасности выполняется в configureInbound, и вам придется адаптировать его к вашему приложению.

authorties - это строковый массив, определяющий, что разрешено, например:

private static String[] authorities = new String[] {
  "VIEW_SCRIPT_TAB", "VIEW_CREDS_TAB"
};

вы определяете в своем GrantedAuthorty объекте.

Если вы не использовали GrantedAuthorty, то можете удалить этот объект.

Убедитесь, что вы включили зависимость spring-security-config в ваш проект

<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-config</artifactId>
  <version>${spring.security.version}</version>
  <type>jar</type>
</dependency>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...