-2

There doesn't seem to a clean and simple example of creating a secure websocket connection anywhere on the interwebs, nor instructions to set one up... any ideas?

whatfield
  • 71
  • 1
  • 7
  • Seriously, you can't Google a webSocket client library that works with Java? – jfriend00 Dec 04 '17 at 03:28
  • Like I said, I can't find a clean example of one, using Java 9 would be optimal. If you see an example working somewhere let me know... – whatfield Dec 09 '17 at 15:02

1 Answers1

0

I would provide some guidelines for websocket authentication. Since websocket is upgraded from http, the authentication is based on http too. You can equip the http connection with ssl or basic or digest auth.

I had worked with spring websocket auth before, ssl is just to upgrade http to https. I would post digest auth for spring websocket here.

1.Configure the server to user digest auth, spring security can get it:

@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.Extend from 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 refer to this post:

spring websocket with digest authentication

Dave Pateral
  • 1,415
  • 1
  • 14
  • 21