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?
Asked
Active
Viewed 345 times
-2
-
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 Answers
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:

Dave Pateral
- 1,415
- 1
- 14
- 21