17

Ich habe WebSocket im Frühjahr implementiert. Alles hat gut funktioniert, aber kürzlich habe ich beschlossen, Spring Security zu implementieren.Spring Security mit WebSockets - Forbidden 403

Meine Message wie folgt aussieht:

@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; 
    } 

} 

Und meine JS-Client sieht liks dieses:

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); 
    }); 

}); 

Spring 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: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> 

Nach über meine JS-Client abonniert I erhalten :

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 

Also beschloss ich, diesen Code in Security Config hinzuzufügen:

<?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> 

aber nach, dass ich wirklich diese Art von Fehlern:

NoSuchBeanDefinitionException: No bean named 'springSecurityMessagePathMatcher' is defined 

Ich weiß nicht, wie solche Bohne definieren, so dass ich erstellt diese unter Klasse:

@Configuration 
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer { 

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

Aber während der Kompilierung erhalte ich diese Art von Fehler:

und ich weiß wirklich nicht, wie das zu beheben :(Ich muss hinzufügen, dass ich Spring Core 4.0.1.RELEASE und Spring Messaging 4.0.1.RELEASE verwenden. Alle mit Spring Security verwandten Bibliotheken befinden sich in der Version 4.0.1.RELEASE.

+1

Ist das Paket Ihrer MessageBroker-Klasse für den Komponentenscan vorhanden? – Jebil

+1

Wenn Sie @EnableCaching verwenden ist ein Fehler https://jira.spring.io/browse/SPR-12336, die SmartInitializingSingleton nicht gefunden gibt. Kannst du vollen Fehler hochladen – Cassian

+1

Ich habe @EnableCaching nicht verwendet –

Antwort

1

Um das zu bekommen dies funktioniert hat Ihre <security:websocket-message-broker >durch eine ID, um es zu ändern Hinzufügen, <security:websocket-message-broker id="interceptor"> und verknüpft es mit der Definition Ihrer websocket Inbound-Kanäle.

<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> 
Verwandte Themen