spring - manager - Seguridad de Primavera con WebSockets-Prohibido 403
spring security order (1)
Para que esto funcione, debe modificar su <security:websocket-message-broker >
agregándole un ID , <security:websocket-message-broker id="interceptor">
y vincularlo a la definición de su websocket de canales entrantes.
<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>
He implementado WebSocket en Spring. Todo funcionó bien, pero recientemente decidí implementar Spring Security.
Mi MessageBroker se parece a:
@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;
}
}
Y mi cliente JS se parece a esto:
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);
});
});
Configuración de seguridad de primavera:
<?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>
Después de suscribirme a través de mi cliente JS recibo:
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
Así que decidí agregar este código en la configuración de seguridad:
<?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>
Pero después de eso recibo este tipo de error:
NoSuchBeanDefinitionException: No bean named ''springSecurityMessagePathMatcher'' is defined
No sé cómo definir tal bean, así que creé esto debajo de la clase:
@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages.simpDestMatchers("/graphs/*").permitAll();
messages.simpDestMatchers("/**").permitAll();
}
}
Pero durante la compilación recibo este tipo de error:
java: cannot access org.springframework.beans.factory.SmartInitializingSingleton
class file for org.springframework.beans.factory.SmartInitializingSingleton not found
y realmente no sé cómo solucionarlo :( Debo agregar que estoy usando Spring Core 4.0.1.RELEASE y Spring Messaging 4.0.1.RELEASE. Todas las librerías relacionadas con Spring Security están en la versión 4.0.1.RELEASE .