如何在客户端与Java建立安全的websocket连接?

时间:2017-12-04 02:43:24

标签: java websocket

似乎没有一个干净简单的例子可以在互联网上的任何地方创建一个安全的websocket连接,也没有说明设置一个......任何想法?

1 个答案:

答案 0 :(得分:0)

我会为websocket身份验证提供一些指导。由于websocket是从http升级的,因此身份验证也基于http。您可以使用ssl或基本或摘要身份验证配置http连接。

之前我曾使用过spring websocket auth,ssl只是将http升级为https。我会在这里为spring websocket发布digest auth。

1.将服务器配置为用户摘要身份验证,弹出安全性可以获取它:

@Configuration  
@EnableWebSecurity  
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {  

    public final static String REALM="MY_REALM";  

    @Autowired  
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {  
        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN")  
        .and().withUser("test").password("test").roles("USER");  
    }  

    @Override  
    protected void configure(HttpSecurity http) throws Exception {  
        http.csrf().disable()  
            .authorizeRequests()  
            .anyRequest().authenticated()  
            .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)  
            .and().exceptionHandling().authenticationEntryPoint(getDigestEntryPoint())  
            .and().addFilter(getDigestAuthenticationFilter(getDigestEntryPoint()));  

    }  

    @Bean  
    public MyDigestAuthenticationEntryPoint getDigestEntryPoint() {  
        MyDigestAuthenticationEntryPoint digestAuthenticationEntryPoint = new MyDigestAuthenticationEntryPoint();  
        digestAuthenticationEntryPoint.setKey("mykey");  
        digestAuthenticationEntryPoint.setNonceValiditySeconds(120);  
        digestAuthenticationEntryPoint.setRealmName(REALM);  
        return digestAuthenticationEntryPoint;  
    }  

    public DigestAuthenticationFilter getDigestAuthenticationFilter(  
            MyDigestAuthenticationEntryPoint digestAuthenticationEntryPoint) throws Exception {  
        DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();  
        digestAuthenticationFilter.setAuthenticationEntryPoint(digestAuthenticationEntryPoint);  
        digestAuthenticationFilter.setUserDetailsService(userDetailsServiceBean());  
        return digestAuthenticationFilter;  
    }  

    @Override  
    @Bean  
    public UserDetailsService userDetailsServiceBean() throws Exception {  
        return super.userDetailsServiceBean();  
    }  
}  
public class MyDigestAuthenticationEntryPoint extends DigestAuthenticationEntryPoint {  

    @Override  
    public void afterPropertiesSet() throws Exception{  
        super.afterPropertiesSet();  
        setRealmName(WebSecurityConfig.REALM);  
    }  
}  

2.从AbstractSecurityWebSocketMessageBrokerConfigurer扩展:

@Configuration  
@EnableWebSocketMessageBroker  
public class WssBrokerConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer  {  

    @Override  
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {  
        messages  
            .nullDestMatcher().authenticated()  
            .simpSubscribeDestMatchers("/topic/notification").permitAll()  
            .simpDestMatchers("/**").authenticated()  
            .anyMessage().denyAll();  
    }  

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

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

    @Bean  
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {  
        ObjectMapper mapper = new ObjectMapper();  
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);  
        MappingJackson2HttpMessageConverter converter =  
                new MappingJackson2HttpMessageConverter(mapper);  
        return converter;  
    }  

    @Override  
    protected boolean sameOriginDisabled() {  
        return true;  
    }  
}  

3.Digest auth for client请参考这篇文章:

spring websocket with digest authentication