• 1000 with: "message": "Не удалось отправить клиентское сообщение приложению через MessageChannel в сеансе. Отправка STOMP ERROR клиенту.", "stack_trace": "org.springframework.security.access.AccessDeniedException: Доступ запрещен.
Я ожидал бы, что использование @WithMockUser(authorities = AuthoritiesConstants.ADMIN)
оставит аутентифицированный контекст для сокета. Что я делаю не так?
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@WithMockUser(authorities = AuthoritiesConstants.ADMIN)
public class SocketIT {
...
@BeforeEach
public void setup() throws Exception {
blockingQueue = new LinkedBlockingDeque<>();
List<Transport> transports = new ArrayList<>();
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
this.sockJsClient = new SockJsClient(transports);
this.stompClient = new WebSocketStompClient(sockJsClient);
this.stompClient.setMessageConverter(new MappingJackson2MessageConverter());
}
@Test
public void shouldReceiveAMessageFromTheServer() throws Exception {
StompSession session = stompClient
.connect(getWsPath(), new StompSessionHandlerAdapter() {})
.get(1, SECONDS);
}
private String getWsPath() {
return String.format("ws://localhost:%d/websocket/tracker", port);
}
@Configuration
public class WebsocketSecurityConfiguration extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
//.nullDestMatcher().authenticated()
.anyMessage().permitAll();
}
@Override
protected boolean sameOriginDisabled() {
return true;
}
}
@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfiguration implements WebSocketMessageBrokerConfigurer {
public static final String IP_ADDRESS = "IP_ADDRESS";
private final JHipsterProperties jHipsterProperties;
public WebsocketConfiguration(JHipsterProperties jHipsterProperties) {
this.jHipsterProperties = jHipsterProperties;
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
String[] allowedOrigins = Optional.ofNullable(jHipsterProperties.getCors().getAllowedOrigins()).map(origins -> origins.toArray(new String[0])).orElse(new String[0]);
registry.addEndpoint("/websocket/tracker")
.setHandshakeHandler(defaultHandshakeHandler())
.setAllowedOrigins(allowedOrigins)
.withSockJS()
.setInterceptors(httpSessionHandshakeInterceptor());
}
@Bean
public HandshakeInterceptor httpSessionHandshakeInterceptor() {
return new HandshakeInterceptor() {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
attributes.put(IP_ADDRESS, servletRequest.getRemoteAddress());
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}
};
}
private DefaultHandshakeHandler defaultHandshakeHandler() {
return new DefaultHandshakeHandler() {
@Override
protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
Principal principal = request.getPrincipal();
if (principal == null) {
Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
principal = new AnonymousAuthenticationToken("WebsocketConfiguration", "anonymous", authorities);
}
return principal;
}
};
}
}
@MessageMapping("/topic/activity")
@SendTo("/topic/tracker")
public ActivityDTO sendActivity(@Payload ActivityDTO activityDTO, StompHeaderAccessor stompHeaderAccessor, Principal principal) {
activityDTO.setUserLogin(principal.getName());
activityDTO.setSessionId(stompHeaderAccessor.getSessionId());
activityDTO.setIpAddress(stompHeaderAccessor.getSessionAttributes().get(IP_ADDRESS).toString());
activityDTO.setTime(Instant.now());
log.debug("Sending user tracking data {}", activityDTO);
return activityDTO;
}