Spring启动时,WebSocket无法从会话获取用户(即java.security.Principal)

Spring启动时,WebSocket无法从会话获取用户(即java.security.Principal),java,session,spring-boot,spring-websocket,Java,Session,Spring Boot,Spring Websocket,使用Spring Boot 1.2.1.释放和弹簧WebSocket。在运行embeddedJetty 9时出现部署运行时问题,当应用程序部署到除localhost之外的任何其他位置时,我无法成功伪造用户(java.security.Principal) 我咨询过 下面的配置(我相信)已经“升级”了一个请求 @Configuration @EnableWebSocketMessageBroker @EnableScheduling public class WebSocketConfig

使用
Spring Boot 1.2.1.释放
弹簧WebSocket
。在运行embedded
Jetty 9
时出现部署运行时问题,当应用程序部署到除localhost之外的任何其他位置时,我无法成功伪造用户(
java.security.Principal

我咨询过

下面的配置(我相信)已经“升级”了一个请求

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

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
    // see http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-handle-broker-relay
    // requires an external broker like AMQP or RabbitMQ
    //registry.enableStompBrokerRelay("/queue/", "/topic/");

    // XXX This might wind up being the impl we actually deploy; but be aware it has certain constraints
    // see http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-message-flow
    registry.enableSimpleBroker("/queue/", "/topic/");
    registry.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/cards").setHandshakeHandler(new UserHandler()).withSockJS();
}

// cheat; ensure that we have a Principal w/o relying on authentication
class UserHandler extends DefaultHandshakeHandler {

    @Override
    protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler,
                    Map<String, Object> attributes) {
        return new TestPrincipal("bogus");
    }
}
但这是我收到的例外

Logger=org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler Type=ERROR Message=Unhandled exception
org.springframework.messaging.simp.annotation.support.MissingSessionUserException: No "user" header in message
at org.springframework.messaging.simp.annotation.support.PrincipalMethodArgumentResolver.resolveArgument(PrincipalMethodArgumentResolver.java:42) ~[spring-messaging-4.1.4.RELEASE.jar!/:4.1.4.RELEASE]
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77) ~[spring-messaging-4.1.4.RELEASE.jar!/:4.1.4.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:127) ~[spring-messaging-4.1.4.RELEASE.jar!/:4.1.4.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:100) ~[spring-messaging-4.1.4.RELEASE.jar!/:4.1.4.RELEASE]
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:451) [spring-messaging-4.1.4.RELEASE.jar!/:4.1.4.RELEASE]
at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:443) [spring-messaging-4.1.4.RELEASE.jar!/:4.1.4.RELEASE]
at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:82) [spring-messaging-4.1.4.RELEASE.jar!/:4.1.4.RELEASE]
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:412) [spring-messaging-4.1.4.RELEASE.jar!/:4.1.4.RELEASE]
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:350) [spring-messaging-4.1.4.RELEASE.jar!/:4.1.4.RELEASE]
at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:135) [spring-messaging-4.1.4.RELEASE.jar!/:4.1.4.RELEASE]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_05]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_05]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_05]
<这里我还有什么要考虑的?

更新

我现在可以在本地主机部署中可靠地重现这一点

有趣的是,在调试模式下使用
STS3.6.3
,当我在
JettyRequestUpgradeStrategy

public JettyRequestUpgradeStrategy(WebSocketServerFactory factory) {
    Assert.notNull(factory, "WebSocketServerFactory must not be null");
    this.factory = factory;
    this.factory.setCreator(new WebSocketCreator() {
        @Override
        public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response) {
            // Cast to avoid infinite recursion
            return createWebSocket((UpgradeRequest) request, (UpgradeResponse) response);
        }
然后继续到
PrincipalMethodArgumentResolver

@Override
public Object resolveArgument(MethodParameter parameter, Message<?> message) throws Exception {
    Principal user = SimpMessageHeaderAccessor.getUser(message.getHeaders());
    if (user == null) {
        throw new MissingSessionUserException(message);
    }
    return user;
}
@覆盖
公共对象resolveArgument(MethodParameter参数,消息)引发异常{
主体用户=SimpMessageHeaderAccessor.getUser(message.getHeaders());
if(user==null){
抛出新的MissingSessionUserException(消息);
}
返回用户;
}

用户
null
。有比赛条件吗?例如,套接字必须在某个时间限制内从请求中获取用户信息吗?

我正在使用Chrome进行浏览器测试。异常在控制台日志中将客户端显示为“在建立连接之前关闭Websocket”。接触,但这是不是:有什么事要做?如何在客户端和服务器端设置备用端口?刚刚发现此:。我将重构并报告我是否成功。你的问题解决了吗?我也有同样的问题,我们能够解决这个问题。
@Override
public Object resolveArgument(MethodParameter parameter, Message<?> message) throws Exception {
    Principal user = SimpMessageHeaderAccessor.getUser(message.getHeaders());
    if (user == null) {
        throw new MissingSessionUserException(message);
    }
    return user;
}