I have a problem. I would be very happy if someone could help me with this. My Spring server successfully receives the message and sends a message to "/queue/private-messages", but my Angular server, which is subscribed, doesn't receive it. Here's my code (I have a user with username "admin1" and ID 2)
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig {
@Autowired
private UserService userService;
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/admin").hasRole("ADMIN")
.requestMatchers("/user").hasRole("USER")
.requestMatchers("/auth/**", "/all", "/websocket/**").permitAll()
.anyRequest().authenticated())
.csrf(AbstractHttpConfigurer :: disable)
.sessionManagement(manager -> manager.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authenticationProvider())
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userService.userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
export class AppComponent implements OnInit {
message: string = ''
anotherUserMessage: string = ''
ownMessage: string = ''
private stompClient: any
private jwtToken: string = 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbjEiLCJpZCI6MiwiaWF0IjoxNzE4MTE1MTY2LCJleHAiOjE3MTgxMTU3NjZ9.Hq-hU704Q7PIrOAWQSOYWPZ55lzJU2eAfSurNkdSEBc';
constructor(private themeService: ThemeServiceService) {}
ngOnInit(): void {
this.themeService.setTheme(this.themeService.getTheme());
this.initConnection();
this.join();
}
private initConnection() {
const URL = '//localhost:8080/websocket'
const socket = new SockJS(URL);
this.stompClient = Stomp.over(socket);
}
private join() {
this.stompClient.connect({}, () => {
this.stompClient.subscribe('/user/queue/private-messages', (message: any) => {
this.anotherUserMessage = JSON.parse(message.body).content;
console.log("FROM SERVER" + message.body)
})
})
}
public sendPrivateMessage() {
console.log(this.message);
this.ownMessage = this.message
const messageJSON = {
messageContent: this.message
};
this.stompClient.send('/ws/private-message', { Authorization: this.jwtToken }, JSON.stringify(messageJSON));
}
}
@Controller
@CrossOrigin
public class WebSocketController {
@MessageMapping("/global-message")
@SendTo("/topic/global-messages")
public ResponseMessage publicMessage(Message message) {
System.out.println(message.getMessageContent());
return new ResponseMessage("From server: " + message.getMessageContent());
}
@MessageMapping("/private-message")
@SendToUser("/queue/private-messages")
public ResponseMessage privateMessage(Message message, SimpMessageHeaderAccessor headerAccessor) {
Authentication authentication = (Authentication) headerAccessor.getUser();
if (authentication != null && authentication.getPrincipal() instanceof UserDetails) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
System.out.println("MESSAGE " + message.getMessageContent());
System.out.println("Sending private message to user: " + userDetails.getUsername());
return new ResponseMessage("Private message for user " + userDetails.getUsername() + ": " + message.getMessageContent());
}
return new ResponseMessage("User not found.");
}
}
@Component
public class WebSocketChannelInterceptor implements ChannelInterceptor {
@Autowired
private final JwtService jwtService;
@Autowired
public WebSocketChannelInterceptor(JwtService jwtService) {
this.jwtService = jwtService;
}
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if(StompCommand.SEND.equals(accessor.getCommand())) {
String token = accessor.getFirstNativeHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7);
System.out.println(token);
UserDetails userDetails = jwtService.loadUserByToken(token);
if (userDetails != null) {
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
accessor.setUser(authentication);
}
}
}
return message;
}
}
I tried to subscribe to the URL with userId.
this.stompClient.subscribe('/user/2/queue/private-messages', (message: any) => {