Spring Security с WebSockets — запрещено 403

Я реализовал WebSocket весной. Все работало нормально, но недавно я решил внедрить Spring Security.

Мой MessageBroker выглядит так:

@Configuration
@EnableWebSocketMessageBroker
@Component("messageBroker")
public class MessageBroker implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        stompEndpointRegistry.addEndpoint("/graphs").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry messageBrokerRegistry) {
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration channelRegistration) {
    }

    @Override
    public void configureClientOutboundChannel(ChannelRegistration channelRegistration) {
    }

    @Override
    public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
        messageConverters.add(new MappingJackson2MessageConverter());
        return false;
    }

}

И мой JS-клиент выглядит так:

var socket = new SockJS('/server/graphs');
var client = Stomp.over(socket);

client.connect({}, function (frame) {
    client.subscribe("/data", function (message) {
        console.log('GET MESSAGE :' + message.body);
        var test = JSON.parse(message.body);
        var point = [ (new Date()).getTime(), parseInt(25) ];
        var shift = randomData.data.length > 60;
        randomData.addPoint(point, true, shift);
    });

});

Весенняя конфигурация безопасности:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security.xsd">

    <security:http auto-config='true' use-expressions="true" disable-url-rewriting="true">
        <security:intercept-url pattern="/login/**" access="isAnonymous()"/>
        <security:intercept-url pattern="/index/**" access="isAuthenticated()" />
        <security:intercept-url pattern="/volumegraph/**" access="isAuthenticated()" />
        <security:intercept-url pattern="/graphs/**" access="permitAll()" />
        <security:intercept-url pattern="/graphs/**/**" access="permitAll()" />
        <security:form-login login-page="/" login-processing-url="/" authentication-failure-url="/" always-use-default-target="true"/>
        <security:csrf/>
        <security:logout logout-success-url="/login"/>
        <security:headers>
            <security:frame-options></security:frame-options>
        </security:headers>
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="user" password="password" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>

</beans>

После подписки через мой JS-клиент я получаю:

Opening Web Socket...
sockjs.js:1213 WebSocket connection to 'ws://localhost:8080/server/graphs/651/kyzdihld/websocket' failed: Error during WebSocket handshake: Unexpected response code: 404
sockjs.js:807 POST http://localhost:8080/server/graphs/651/zx7zdre7/xhr_streaming 403 (Forbidden)AbstractXHRObject._start @ sockjs.js:807(anonymous function) @ sockjs.js:834
sockjs.js:807 POST http://localhost:8080/server/graphs/651/o6eg5ikc/xhr 403 (Forbidden)AbstractXHRObject._start @ sockjs.js:807(anonymous function) @ sockjs.js:834
stomp.js:122 Whoops! Lost connection to undefined

Поэтому я решил добавить этот код в Security Config:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security.xsd">

<security:websocket-message-broker>
    <!--<security:intercept-message pattern="/graphs/**" access="permitAll()"/>-->
    <security:intercept-message pattern="/**" access="permitAll()"/>
    <security:intercept-message type="SUBSCRIBE" access="permitAll()"/>
    <security:intercept-message type="CONNECT" access="permitAll()"/>
</security:websocket-message-broker>

</beans>

но после этого я получаю такую ​​​​ошибку:

NoSuchBeanDefinitionException: No bean named 'springSecurityMessagePathMatcher' is defined

Я не знаю, как определить такой компонент, поэтому я создал следующий класс:

@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
        messages.simpDestMatchers("/graphs/*").permitAll();
        messages.simpDestMatchers("/**").permitAll();
    }
}

Но во время компиляции я получаю такую ​​ошибку:

java: cannot access org.springframework.beans.factory.SmartInitializingSingleton
  class file for org.springframework.beans.factory.SmartInitializingSingleton not found

и я действительно не знаю, как это исправить :( Я должен добавить, что я использую Spring Core 4.0.1.RELEASE и Spring Messaging 4.0.1.RELEASE. Все библиотеки, связанные с Spring Security, находятся в версии 4.0.1.RELEASE. .


person Lukasz Ciesluk    schedule 02.06.2015    source источник
comment
находится ли пакет вашего класса MessageBroker для сканирования компонентов?   -  person Jebil    schedule 14.07.2015
comment
Если вы используете @EnableCaching, это ошибка jira.spring.io/browse/SPR-12336, что дать SmartInitializingSingleton не найдено. Можете ли вы загрузить полную ошибку   -  person Cassian    schedule 14.07.2015
comment
Я не использовал @EnableCaching   -  person Lukasz Ciesluk    schedule 14.07.2015
comment
@Jebil Да, я думаю, что это так. Там вы можете увидеть github.com/GarciaPL/CurrencyFair/blob/master/currencyfair/, но это не тот случай. Это приложение изменено таким образом, чтобы не использовать безопасность для MessageBroker.   -  person Lukasz Ciesluk    schedule 14.07.2015
comment
Похоже, вы не добавили currencyfair-consumer-ctx.xml в свой 'web.xml', и он находится в папке ресурсов, а не в WEB-INF. Проверьте это, и я думаю, что проблема есть.   -  person Jebil    schedule 15.07.2015
comment
В web.xml вы можете найти root-consumer-ctx.xml, который включает в себя currencyfair-consumer-ctx.xml. github.com/GarciaPL/CurrencyFair/blob/master/currencyfair/   -  person Lukasz Ciesluk    schedule 15.07.2015
comment
Вы пытались добавить первый xml в <security:http> <security:intercept-url pattern="/server/graphs/**" access="permitAll()" /> ? Кстати <security:intercept-url pattern="/graphs/**" access="permitAll()" /> <security:intercept-url pattern="/graphs/**/**" access="permitAll()" /> - вам не нужен второй шаблон, потому что '/graphs/**' ant match уже использует его, и он избыточен.   -  person Mati    schedule 21.07.2015


Ответы (1)


Чтобы это заработало, вам нужно изменить <security:websocket-message-broker >, добавив к нему некоторый идентификатор, <security:websocket-message-broker id="interceptor"> и связать его с определением ваших входящих каналов веб-сокета.

<websocket:message-broker  application-destination-prefix="/app" user-destination-prefix="/user" >
 <websocket:stomp-endpoint path="/websocketEndPoint" >
 <websocket:handshake-handler ref="astalavista" />
 <websocket:simple-broker prefix="/topic , /queue"  /> 
 <websocket:client-inbound-channel >
   <websocket:interceptors>
   <!--This will reference your interceptor that you have defined in you security XML-->
      <ref bean="interceptor"/>
   </websocket:interceptors>
 </websocket:client-inbound-channel>
</websocket:message-broker>
person VendettaTurkey    schedule 27.07.2015