Websocket AccessDeniedException весной - PullRequest
0 голосов
/ 16 мая 2018

Это мои конфиг-классы:

@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: функция 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, но я не был уверен, что это правильное решение. Может ли кто-нибудь помочь мне с этим?

...