弹簧安全腹板

时间:2015-09-18 12:21:40

标签: spring authentication spring-security

我尝试使用spring security在websockets上添加身份验证时遇到问题。 此时我已经配置了http以使用当前的安全配置,它工作正常 - 我能够对用户进行身份验证,并返回经过身份验证的主体。但是我想添加一些websocket安全性,一旦我把下面的类应用程序记录下来,但它不想打开任何websockets:

@Configuration
public class WebSocketSecurityConfig extends
        AbstractSecurityWebSocketMessageBrokerConfigurer {
    protected void configureInbound(
            MessageSecurityMetadataSourceRegistry messages) {
        messages.nullDestMatcher().permitAll().simpDestMatchers("/app/**")
                .authenticated()
                .simpSubscribeDestMatchers("/user/*", "/topic/*")
                .authenticated();

        // TODO
    }

    @Override
    protected boolean sameOriginDisabled() {
        return true;
    }
}

WebSocketSecurityConfig已正确初始化,因为当我添加permitAll()而不是authenticated()时,它允许我打开websocket。 我确信如果http主体经过身份验证,那么websocket主体也会被验证。我用这个作为参考: http://docs.spring.io/spring-security/site/docs/current/reference/html/websocket.html

以下是控制台中的错误:

org.springframework.messaging.MessageDeliveryException: Failed to send message to ExecutorSubscribableChannel[clientInboundChannel]; nested exception is org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:127)
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:104)
at org.springframework.web.socket.messaging.StompSubProtocolHandler.handleMessageFromClient(StompSubProtocolHandler.java:266)
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.handleMessage(SubProtocolWebSocketHandler.java:309)
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleMessage(WebSocketHandlerDecorator.java:75)
at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.handleMessage(LoggingWebSocketHandlerDecorator.java:56)
at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.handleMessage(ExceptionWebSocketHandlerDecorator.java:72)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.handleTextMessage(StandardWebSocketHandlerAdapter.java:112)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.access$000(StandardWebSocketHandlerAdapter.java:42)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:82)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:79)
at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:393)
at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:494)
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:289)
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:130)
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:56)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:203)
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:203)
at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:92)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:609)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232)
    at org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor.preSend(ChannelSecurityInterceptor.java:71)
    at org.springframework.messaging.support.AbstractMessageChannel$ChannelInterceptorChain.applyPreSend(AbstractMessageChannel.java:158)
    at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:113)
    ... 24 more

我的配置类:

@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

@Autowired
HandshakeHandler handshakeManager;

@Autowired
AbstractManagerEventListener eventListenerHandler;

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

@Override
public void configureWebSocketTransport(
        WebSocketTransportRegistration registration) {
    registration.setMessageSizeLimit(512 * 1024);
    registration.setSendBufferSizeLimit(1024 * 1024);
    registration.setSendTimeLimit(40000);
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/channelSocket").setHandshakeHandler(
            handshakeManager);
}

@Bean
public HandshakeHandler handshakeManager() throws Exception {
    return new HandshakeManager();
}

}

我的HandshakeHandler课程:

public class HandshakeManager extends DefaultHandshakeHandler {

    @Override
    protected Principal determineUser(ServerHttpRequest request,
            WebSocketHandler wsHandler, Map<String, Object> attributes) {

        Principal principal = request.getPrincipal();
        return new UserPrincipal(principal.getName());
    }
}

determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes)

返回与经过身份验证的用户的主体相同的主体。 任何帮助表示赞赏!谢谢!

0 个答案:

没有答案