带有基于Spring的SockJS/STOMP Web套接字的JSON Web令牌(JWT) [英] JSON Web Token (JWT) with Spring based SockJS / STOMP Web Socket

查看:425
本文介绍了带有基于Spring的SockJS/STOMP Web套接字的JSON Web令牌(JWT)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring Boot(1.3.0.BUILD-SNAPSHOT)设置一个RESTful Web应用程序,该应用程序包括一个STOMP/SockJS WebSocket,我打算从iOS应用程序和Web浏览器中使用它.我想使用 JSON Web令牌(JWT)来保护REST请求和WebSocket接口,但是后者却遇到了困难.

I am in the process of setting up a RESTful web application using Spring Boot (1.3.0.BUILD-SNAPSHOT) that includes a STOMP/SockJS WebSocket, which I intend to consume from an iOS app as well as web browsers. I want to use JSON Web Tokens (JWT) to secure the REST requests and the WebSocket interface but I’m having difficulty with the latter.

该应用受Spring Security保护:-

The app is secured with Spring Security:-

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    public WebSecurityConfiguration() {
        super(true);
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("steve").password("steve").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .exceptionHandling().and()
            .anonymous().and()
            .servletApi().and()
            .headers().cacheControl().and().and()

            // Relax CSRF on the WebSocket due to needing direct access from apps
            .csrf().ignoringAntMatchers("/ws/**").and()

            .authorizeRequests()

            //allow anonymous resource requests
            .antMatchers("/", "/index.html").permitAll()
            .antMatchers("/resources/**").permitAll()

            //allow anonymous POSTs to JWT
            .antMatchers(HttpMethod.POST, "/rest/jwt/token").permitAll()

            // Allow anonymous access to websocket 
            .antMatchers("/ws/**").permitAll()

            //all other request need to be authenticated
            .anyRequest().hasRole("USER").and()

            // Custom authentication on requests to /rest/jwt/token
            .addFilterBefore(new JWTLoginFilter("/rest/jwt/token", authenticationManagerBean()), UsernamePasswordAuthenticationFilter.class)

            // Custom JWT based authentication
            .addFilterBefore(new JWTTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }

}

WebSocket配置是标准的:-

The WebSocket configuration is standard:-

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

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

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").withSockJS();
    }

}

我还有一个AbstractSecurityWebSocketMessageBrokerConfigurer的子类来保护WebSocket:-

I also have a subclass of AbstractSecurityWebSocketMessageBrokerConfigurer to secure the WebSocket:-

@Configuration
public class WebSocketSecurityConfiguration extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
        messages.anyMessage().hasRole("USER");
    }

    @Override
    protected boolean sameOriginDisabled() {
        // We need to access this directly from apps, so can't do cross-site checks
        return true;
    }

}

还有两个带有@RestController注释的类,可以处理各种功能,并且通过在我的WebSecurityConfiguration类中注册的JWTTokenFilter成功地保护了这些位.

There is also a couple of @RestController annotated classes to handle various bits of functionality and these are secured successfully via the JWTTokenFilter registered in my WebSecurityConfiguration class.

但是我似乎无法用JWT保护WebSocket.我正在使用 SockJS 1.1.0 会出现 SockJS不允许使用初始/info和/或握手发送参数请求.

However I can't seem to get the WebSocket to be secured with JWT. I am using SockJS 1.1.0 and STOMP 1.7.1 in the browser and can't figure out how to pass the token. It would appear that SockJS does not allow parameters to be sent with the initial /info and/or handshake requests.

Spring Security for WebSockets文档状态 AbstractSecurityWebSocketMessageBrokerConfigurer确保:

任何入站CONNECT消息都需要有效的CSRF令牌来实施相同起源策略

Any inbound CONNECT message requires a valid CSRF token to enforce Same Origin Policy

这似乎暗示着初始握手应该是不安全的,并且在接收到STOMP CONNECT消息时将调用身份验证.不幸的是,我似乎找不到任何有关执行此操作的信息.此外,这种方法还需要其他逻辑来断开打开WebSocket连接且从不发送STOMP CONNECT的流氓客户端的连接.

Which seems to imply that the initial handshake should be unsecured and authentication invoked at the point of receiving a STOMP CONNECT message. Unfortunately I can't seem to find any information with regards to implementing this. Additionally this approach would require additional logic to disconnect a rogue client that opens a WebSocket connection and never sends a STOMP CONNECT.

对Spring非常(非常),我也不确定Spring Sessions是否适合于此.尽管文档非常详细,但似乎没有一个很好的,简单的(又称白痴)指南来说明各个组件如何组合在一起/如何相互影响.

Being (very) new to Spring I'm also not sure if or how Spring Sessions fits into this. While the documentation is very detailed there doesn't appear to a nice and simple (aka idiots) guide to how the various components fit together / interact with each other.

我该如何通过提供JSON Web令牌来保护SockJS WebSocket,最好是在握手时(甚至可能)?

How do I go about securing the SockJS WebSocket by providing a JSON Web Token, preferably at the point of handshake (is it even possible)?

推荐答案

SockJS客户端似乎已添加了对查询字符串的支持,请参见

Seems like support for a query string was added to the SockJS client, see https://github.com/sockjs/sockjs-client/issues/72.

这篇关于带有基于Spring的SockJS/STOMP Web套接字的JSON Web令牌(JWT)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆