Spring中的Websocket AccessDeniedException

时间:2018-05-16 17:14:03

标签: spring-boot spring-websocket

这些是我的配置类:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private CustomUserServiceDetails customUserServiceDetails;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/", "/home", "/proc/**", "/css/**", "/js/**", "/webjars/**", "/voting-socket/topic/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }

    @Autowired
    public void configureAuth(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserServiceDetails);
    }

}


@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

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

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/voting-socket").withSockJS();
    }
}


@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
        messages
                .nullDestMatcher().authenticated() // 1
                .simpSubscribeDestMatchers("/topic/**").permitAll()
                .simpDestMatchers("/app/**").hasRole("ADMIN")
                .anyMessage().denyAll(); // 2

    }

}

和javascript客户端代码: function connect(vm){

    let socket = new SockJS('/voting-socket');
    stompClient = Stomp.over(socket);
    let headers = {};
    headers[headerName] = token;
    stompClient.connect(headers, function (frame) {
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/voting/' + procId, function (data) {
            console.log("data: " + data.body);
        });
    });

现在,根据我的理解,我应该能够订阅并从/voting-socket/topic websocket端点获取数据而无需任何验证,但是我收到此错误:(来自chrome控制台的日志)

Opening Web Socket...
stomp.min.js:8 Web Socket Opened...
stomp.min.js:8 >>> CONNECT
X-CSRF-TOKEN:e0193869-8753-4eb7-b5fe-bc130796c3b1
accept-version:1.1,1.0
heart-beat:10000,10000


stomp.min.js:8 <<< ERROR
message:Failed to send message to ExecutorSubscribableChannel[clientInboundChannel]; nested exception is org.springframework.security.access.AccessDeniedException\c Access is denied
content-length:0 

所以我希望这段代码能够在没有任何身份验证(登录)的情况下从/voting-socket/topic/proc/**订阅和获取数据,并且只允许具有特定角色的登录用户将数据发送到/voting-socket/app/proc/**

通过一些测试,我设法使其能够删除第1行和第2行,但不确定它是否是正确的解决方案。有人可以帮我这个吗?

0 个答案:

没有答案