Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpringBoot with WebSockets, @PreAuthorize header not working

I am using SpringBoot 2.0 (Spring 5.0.4) with SpringSecurity and STOMP (Websockets). My connect endpoint is protected, and Authorization using @PreAuthorize on all of my standard REST endpoints works correctly. However, when I add @PreAuthorize to my STOMP message handlers I get the exception below.

I have a channel interceptor, and in the preSend method,I can see that the user principal is there on the StompHeaderAccessor.

It seems that something failed to initialize the SecurityContext... Any ideas on where this should be intialized?

org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:379)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:223)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
    at com.vertafore.ws.controller.EventStompControllerV1$$EnhancerBySpringCGLIB$$33f954c1.processMessageFromClient(<generated>)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:181)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:114)
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:517)
    at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:495)
    at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:88)
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:475)
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:411)
    at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:138)
    at org.springframework.cloud.sleuth.instrument.async.TraceRunnable.run(TraceRunnable.java:62)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.base/java.lang.Thread.run(Thread.java:844)
like image 648
Sean Scott Avatar asked Nov 27 '25 11:11

Sean Scott


1 Answers

This solved it in my case. Note, I am using spring-security 5.

The relevant line I was missing was messages.simpDestMatchers("/live/**").authenticated();. Without that, I ran into the same Exception.

Also, sameOriginDisabled is to disable CSRF if you have this problem aswell.

@Configuration
@EnableWebSocketMessageBroker
public class RegaDAWSWebsocketConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Value("${websocket.heartbeatInterval}")
    private int heartbeatInterval;

    @Value("${websocket.useSockJS}")
    private boolean useSockJS;

    @Value("${websocket.allowedOrigins}")
    private String allowedOrigins;

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

    @Override
    public void registerStompEndpoints(@NotNull final StompEndpointRegistry registry) {
        // Allowing both plain Websocket and SockJS
        if (useSockJS) {
            registry.addEndpoint("/live")
                    .setAllowedOriginPatterns(allowedOrigins)
                    .withSockJS()
                    .setHeartbeatTime(heartbeatInterval);
        } else {
            registry.addEndpoint("/live").setAllowedOriginPatterns(allowedOrigins);
        }
    }

    @Override
    protected void configureInbound(final MessageSecurityMetadataSourceRegistry messages) {
        messages.simpDestMatchers("/live/**").authenticated();
    }

    @Override
    protected boolean sameOriginDisabled() {
        return true;
    }
}
like image 115
kistlers Avatar answered Dec 01 '25 14:12

kistlers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!