似乎没有一个干净简单的例子可以在互联网上的任何地方创建一个安全的websocket连接,也没有说明设置一个......任何想法?
答案 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请参考这篇文章: