Websocket with Springboot Microservice giving 403 access denied

I am developing a api for websocket using SpringBoot and when i am trying to access or connecting websocket using Angular its always giving 403 Forbidden.But same api example http://localhost:8080/ws is connecting through postman by passing Basic auth but its failed from angular

error
Java code
WebSocketConfig

‘’’
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableSimpleBroker("/topic");  
    config.setApplicationDestinationPrefixes("/app"); 
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/ws")
    
            .setAllowedOrigins("http://localhost:4200")
            .setAllowedOriginPatterns("http://localhost:*")
            .withSockJS();
}
@Bean
@Primary
public ThreadPoolTaskExecutor customClientInboundChannelExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(5);
    executor.setMaxPoolSize(10);
    executor.setQueueCapacity(500);
    executor.setThreadNamePrefix("custom-clientInbound-");
    return executor;
}

}

‘’’
webconfig

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/simulation-alert/**")  
            .allowedOrigins("http://localhost:4200")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
            .allowedHeaders("*")
           .allowCredentials(true);
}

}

Angular

export class WebSocketService {
private socket: WebSocket | null = null; // Initialize with null
private messageSubject = new BehaviorSubject(null);
message$ = this.messageSubject.asObservable();

constructor(private http: HttpClient) {}

// Step 1: Authenticate via HTTP request
authenticate() {
const myHeaders = new Headers();
myHeaders.append(‘Authorization’, ‘Basic …==’);
myHeaders.append(‘Cookie’, ‘JSESSIONID=633580394D50A0EFC7793BF02FAFB889’);

const requestOptions: RequestInit = {
method: ‘GET’,
headers: myHeaders,
redirect: ‘follow’

};

fetch(‘http://localhost:8080/ws’, requestOptions)
.then((response: Response) => { // Explicitly type the parameter as Response
if (response.ok) {
// Step 2: After successful authentication, establish WebSocket connection
this.connectWebSocket();
} else {
throw new Error(‘Authentication failed’);
}
})
.catch((error) => console.error(‘Authentication error:’, error));
}

// Step 2: Establish WebSocket connection after authentication
private connectWebSocket() {
this.socket = new WebSocket(‘ws://localhost:8080/simulation-alert’); // Use your WebSocket URL

this.socket.onopen = () => {
  console.log('WebSocket connection established');
};

this.socket.onmessage = (event) => {
  const message = JSON.parse(event.data);
  this.messageSubject.next(message); // Emit received message
};

this.socket.onerror = (error) => {
  console.error('WebSocket error:', error);
};

this.socket.onclose = (event) => {
  console.log('WebSocket connection closed:', event);
};

}

Is this somehow related to Cumulocity? It seems to be generic issue and I guess there is just something wrong in your configuration. Could be on server-level, your allowedOrigins seems to be stange when limiting to localhost only, or client level e.g. not passing the correct credentials.

Also it’s not very clear which credentials are checked on server side and provided by the angular client.

If it is Cumulocity related there are many pointers that it will never work like that running within cumulocity, e.g. ports, localhost, insecure http etc.

I have used Storm client and socketjs also and have passed correct Auth header from angular like how i did with http request but its failing .I have used cumulocity Microservice with Springboot and here is error i am getting Set SecurityContextHolder to anonymous SecurityContext
Failed to authorize filter invocation [GET /simulation-alert] with attributes [fullyAuthenticated]
Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint@31ba1da3
2025-01-22 14:00:08.928 DEBUG 17456 — [io-8080-exec-10] o.s.security.web.FilterChainProxy : Securing GET /error

It doesn’t look like implemented for Cumulocity because it is ignoring a lot of core principles:

  • http is not allowed
  • localhost as origin will not work
  • Authentication is handled by Cumulocity using Cumulocity credentials
  • For Angular you should use the client provided by the sdk (you don’t need to handle any authentication anymore with it).

I am currently working on a project where I am using Angular as the frontend, running locally, and need to implement WebSocket communication with a Cumulocity backend. However, I’m facing some challenges with configuring the WebSocket connection, especially cumulocity auth over ws.

Could you kindly assist by providing any documentation or references regarding how to implement WebSocket communication using the Cumulocity SDK in this scenario?

Any guidance or examples would be greatly appreciated!

First of all Cumulocity provides a real-time API that can be used out of the box by Angular as services are part of a the Web SDK:

https://styleguide.cumulocity.com/apps/codex/#/develop/services/RealtimeService/overview

I would explore this path before going the whole microservice, application via websocket path.

If you really need to implement a custom web socket endpoint in a microservice, you have take care about the limits the microservice has:

  • Only communication via port 443 + https / wss
  • Endpoints are automatically protected and a cumulocity user must be authenticate. When starting from local environment the user must contain tenantId/user when using the SDK.
  • The endpoints always start with /service/<MicroserviceName>/. here you can add /simulation-alert/
  • You can test the microservice locally with localhost but it will be different when uploaded, so I would avoid that. Also in local test you must provide cumulocity credentials to authenticate against endpoints.

In angular you shouldn’t use any httpClient but the SDK client.
I’m don’t fully understand what you are doing there… you don’t need to authenticate with a GET call and calling a websocket afterwards. Establishing a websocket connection actually contains the authentication.