如何增加弹簧5腹板的安全性

时间:2018-04-24 14:42:38

标签: java spring spring-boot spring-security websocket

我遵循了以下教程:Using WebSocket to build an interactive web application

一切都按照描述工作,并且aplication看起来很好。我只有一个不错的控制器:

@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()) + "!");
    }

}

还有点配置。

现在我想为这个简单的应用程序添加安全性。我花时间找一个例子,但我找不到它。

一般来说,我找到了教程:

Preview Spring Security WebSocket Support

但看起来这个例子只与春天4相关而不是春天5.而且我不明白我应该在哪里提供凭证等等。描述不够详细,不适用于我的例子。

我发现了另外一个教程: Websocket Authentication and Authorization in Spring Ask

它看起来更清晰,但我不确定它是目前最好的解决方案。

您能否建议为我的应用程序配置弹簧安全性的最简单方法?

P.S。此外,我发现不一样但熟悉的问题How to secure websocket application [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();
    }
}

当我启动应用程序时,我看到stacktrace:

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 :(得分:0)

您链接的帖子也适用于spring 5 websockets,是最简单的扩展解决方案 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>

答案 1 :(得分:0)

提供与不兼容的库版本相关的堆栈跟踪。

如果使用正确的依赖项,它会起作用。例如:

compile ('org.springframework.security:spring-security-messaging:5.0.4.RELEASE')
compile ('org.springframework.security:spring-security-web: 5.0.4.RELEASE')