【问题标题】:Access UserDetails object in Websocket session Spring MVC在 Websocket 会话 Spring MVC 中访问 UserDetails 对象
【发布时间】:2014-09-17 11:58:36
【问题描述】:

在 Spring MVC 4 应用程序中通过 websocket 连接发送的调用中,当将其作为参数添加到方法中时,我可以获得 java.security.Principal 对象。

但是,这基本上只有用户名,我需要在登录时创建的(扩展的)UserDetails 对象。

SecurityContextHolder.getContext().getAuthentication() 返回null。据我了解,因为 spring 创建了一个特殊的会话来处理 websocket 连接。

问题:有没有办法从 websocket 会话/线程内部访问安全上下文?

(能够访问会话 bean 也足够了)。

【问题讨论】:

  • 对于其他人:我使用 Spring Session 解决了这个问题。 projects.spring.io/spring-session。根本不喜欢这个解决方案,因为它需要我保留 websocketsessions 和 httpsession 之间的映射。感觉丑陋和不安全,但我必须让它工作。将保持这个问题开放,以便获得更优雅的解决方案。

标签: spring-mvc spring-security websocket spring-websocket


【解决方案1】:

@AuthenticationPrincipal 专门用于 REST/MVC 方法。

但是,您可以通过将 java.security.Principle 类型的参数添加到您的 @MessageMapping 注释方法中,然后从中获取真正的 UserDetails 对象,如下所示:

FooUserDetails currentUser = (FooUserDetails) ((Authentication) user).getPrincipal();

这适用于我的 Spring Boot 1.5.4

【讨论】:

    【解决方案2】:

    我想你已经扩展了 AbstractWebSocketHandler

    你可以有主体名称:

    @Override
    public void afterConnectionEstablished ( WebSocketSession session ) throws Exception {
        logger.info ( "afterConnectionEstablished = " + session.getPrincipal () );
    }
    

    【讨论】:

    • 我在 onMessage 调用的方法中需要它(使用@MessageMapping)。
    【解决方案3】:

    我还没有测试过,但你应该能够访问你的用户添加一个参数,如

    @AuthenticationPrincipal CustomUser customUser
    

    到您的@MessageMapping 方法。

    您可以在这里找到更多信息:http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#mvc-authentication-principal

    【讨论】:

    • 有趣的注释(不知道它的存在)。但是可能会起作用:我无法通过 atm 测试来验证这一点。
    • @AuthenticationPrincipal 仅适用于 REST 控制器方法,不适用于 websocket。您引用的链接是专门针对 mvc 的。
    猜你喜欢
    • 1970-01-01
    • 2013-10-19
    • 2015-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    相关资源
    最近更新 更多