鉴于以下配置,与"/connect"
的初始websocket握手成功进行基本身份验证。但是,当我通过活动websocket发送帧时,我得到以下异常:org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
。
当我从@PreAuthorize
"/sendMessage"
中删除WebsocketController
注释时,我没有收到异常。 Spring文档说明初始HTTP握手中的Authentication
应该在SecurityContext中为未来的websocket框架设置,但这似乎不会自动发生。
我应该如何为websocket连接设置Authentication
?
@Configuration
@EnableWebSocket
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config){
config.enableStompBrokerRelay("/outbound");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/connect").withSockJS();
}
}
//...............
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationProvider authProvider;
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and().httpBasic()
;
}
@Autowired
public void configureAuthentication(final AuthenticationManagerBuilder authBuilder) throws Exception {
authBuilder.authenticationProvider(authProvider);
}
}
//.............
@Controller
public class WebSocketController {
// This fails despite successful websocket handshake
@MessageMapping("/sendMessage")
@SendTo("/outbound/message")
@PreAuthorize("hasRole('USER')")
public Message message(@Payload Message message) {
return "web socket message";
}
// This HTTP call succeeds
@RequestMapping("/httpEndpoint")
@PreAuthorize("hasRole('USER')")
public @ResponseBody String doSomething(){
return "some response";
}
}
// ..................
@Component
public class MyAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
// all are valid
return new UsernamePasswordAuthenticationToken(username, password, Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
}
@Override
public boolean supports(final Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
答案 0 :(得分:0)
Spring WebSockets似乎不支持SpringSecurity注释,因此必须使用以下命令配置安全性:
@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(final MessageSecurityMetadataSourceRegistry messages) {
messages.anyMessage().authenticated()
.simpDestMatchers("/**").hasRole("USER")
;
}
}