【问题标题】:Secure Spring-Webscoket using spring-security and access principal from websocket message使用 spring-security 保护 Spring-Websocket 并从 websocket 消息访问主体
【发布时间】:2014-10-27 18:00:55
【问题描述】:

Spring Security 是一个非常好的框架,广泛用于身份验证和授权。

我有一个要求,应用程序要使用 j_spring_security_check 进行身份验证,并且只有授权用户才能向 websocket 处理程序发出请求。

我已经按照http://malalanayake.wordpress.com/2014/06/27/spring-security-on-rest-api/配置了spring security

我已经按照http://syntx.io/using-websockets-in-java-using-spring-4/配置了websocket。

我希望从 handleTextMessage 处理程序访问 MyPrincipal 主体对象,如下所示:

    @Override
    protected void handleTextMessage(WebSocketSession session,
            TextMessage message) throws Exception {
        System.out.println("Protocol: "+session.getAcceptedProtocol());
        TextMessage returnMessage = new TextMessage(message.getPayload()
                + " received at server");
        System.out.println("myAttrib="
                + session.getAttributes().get("myAttrib"));
        MyPrincipal user = (MyPrincipal) ((Authentication) session
                .getPrincipal()).getPrincipal();
        System.out.println("User: " + user.getUserId());
        session.sendMessage(returnMessage);
    }

请尽快重播。

【问题讨论】:

    标签: java spring spring-security websocket


    【解决方案1】:

    在 websocket 配置中添加 HttpSessionHandshakeInterceptor 允许将 spring 安全主体对象从 SpringSecurityContext 传递到 WebsocketSession

    编辑: HandshakeInterceptor.java

    public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor{
    
        @Override
        public boolean beforeHandshake(ServerHttpRequest request,
                ServerHttpResponse response, WebSocketHandler wsHandler,
                Map<String, Object> attributes) throws Exception {
            System.out.println("Before Handshake");
            return super.beforeHandshake(request, response, wsHandler, attributes);
        }
    
        @Override
        public void afterHandshake(ServerHttpRequest request,
                ServerHttpResponse response, WebSocketHandler wsHandler,
                Exception ex) {
            System.out.println("After Handshake");
            super.afterHandshake(request, response, wsHandler, ex);
        }
    
    }
    

    websocket.xml

    <bean id="websocket" class="co.syntx.example.websocket.handler.WebsocketEndPoint"/>
    
    <websocket:handlers>
        <websocket:mapping path="/websocket" handler="websocket"/>
        <websocket:handshake-interceptors>
        <bean class="co.syntx.example.websocket.HandshakeInterceptor"/>
        </websocket:handshake-interceptors>
    </websocket:handlers>
    

    【讨论】:

    • 我想将 spring 安全主体传递给 WebSocket,我在代码中添加了 HandShakeInterceptor 但它仍然抛出 401 错误。我没有 websocket.xml 文件,如何配置或者可以在代码中实现?
    • 在类中添加@Component注解。假设您没有 xml - 您从一些 spring 配置注释或 smth 进行组件扫描;如果您谈论如何配置 websocket - 有专门的教程(有整个动作类)
    【解决方案2】:

    确保您使用 Spring Security 保护您的 WebSocket Endpoint 并进行了登录。 (如果未完成,则为 401。)

    Testet 与 3.2.7 和 4.0.2.RELEASE

    两个版本都有:

    • session.getPrincipal()
    • SecurityContextHolder.getContext().getAuthentication()

      @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
      protected void configure(HttpSecurity http) throws Exception {
          http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
              .and()
              .httpBasic().and()
              .authorizeRequests()
      

    【讨论】:

    • 当 websocket 客户端使用 Spring Security 连接到服务器时出现 401 错误,如何保护端点。能详细描述一下吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    • 2014-08-15
    • 1970-01-01
    • 2019-06-11
    • 2017-06-14
    • 1970-01-01
    • 2018-11-05
    相关资源
    最近更新 更多