zoukankan      html  css  js  c++  java
  • 使用Spring STOMP时ChannelInterceptor无法获取用户信息

    Spring中websocket相关的Bean有一个专门的Scope——websocket,因此这在这些Bean当中是无法注入Scope为request的各种Bean的。这也挺正常的,一个websocket可能会持续很长时间,request的各种Bean仅仅在握手的时候有用,一直不释放也不是个办法。

    STOMP中用户身份认证主要来自于握手的Http请求,具体来说来源于方法DefaultHandshakeHandler#getUser()。各种Web的机制在这里也基本都适用。但当客户端请求连接各种TOPIC,特别是各种动态的TOPIC时,鉴权的问题就有点不一样了。Spring文档中有这一句:

    When a WebSocket handshake is made and a new WebSocket session is created, Spring’s WebSocket support automatically propagates the java.security.Principal from the HTTP request to the WebSocket session.

    也就是说request中的Principal会自动转到websocket中去,很好。然后我们可以利用ChannelInterceptor来拦截订阅请求。但这时候发现,Principal居然是null

    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);
        if (StompCommand.SUBSCRIBE.equals(headerAccessor.getCommand())) {
            Principal principal = headerAccessor.getUser();
            // principal is null here
        }
        return message;
    }
    

    原因倒是很简单,SpringBoot的starter少了一个依赖:

    compile 'org.springframework.security:spring-security-messaging'
    

    缺少这个库不会引发任何异常也没有任何Log,但是会使得上面的代码拿不到Principal。可以说各种AutoConfiguration还是挺容易留下这种坑的。SpringBoot的各种Starter用来很爽,就是很容易让人知其然不知其所以然,太多的细节被隐藏了,如果程序工作得好倒还OK,一旦出现问题,连从哪里开始排查都不知道。像上面的情况,引入的相关的Starter,但是需要的特性还要格外的依赖,文档中又没有说明,是最容易踩到的大坑。

  • 相关阅读:
    mysql数据类型
    Hive Getting Started补充
    Hive安装
    HDFS High Availability Using the Quorum Journal Manager
    用DBContext (EF) 实现通用增删改查的REST方法
    Internet Explorer 10 administration IE10管理
    配置AD RMS及SharePoint 2013 IRM问题解决及相关资源
    SharePoint 2013 首页修改
    Status: Checked in and viewable by authorized users 出现在sharepoint 2013 home 页面
    添加AD RMS role时,提示密码不能被验证The password could not be validated
  • 原文地址:https://www.cnblogs.com/narcissu5/p/8337822.html
Copyright © 2011-2022 走看看