Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullPointerException in AuthenticationContext.logout() because VaadinServletResponse is null #20017

Open
sephiroth-j opened this issue Sep 20, 2024 · 0 comments

Comments

@sephiroth-j
Copy link

sephiroth-j commented Sep 20, 2024

Description of the bug

I followed the example of enabling security using Spring Security. I added a logout button and used AuthenticationContext.logout() as described in the example.

Instead of logging out, nothing happens because a NullPointerException is thrown here

HttpServletResponse response = VaadinServletResponse.getCurrent()
.getHttpServletResponse();

The example when not using AuthenticationContext clearly does not try to use VaadinServletResponse because it is a) null and b) not used by the logout handler.

example without AuthenticationContext

    public void logout() {
        UI.getCurrent().getPage().setLocation(LOGOUT_SUCCESS_URL);
        SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler();
        logoutHandler.logout(
                VaadinServletRequest.getCurrent().getHttpServletRequest(), null,
                null);
    }

stacktrace

java.lang.NullPointerException: Cannot invoke "com.vaadin.flow.server.VaadinServletResponse.getHttpServletResponse()" because the return value of "com.vaadin.flow.server.VaadinServletResponse.getCurrent()" is null
	at com.vaadin.flow.spring.security.AuthenticationContext.logout(AuthenticationContext.java:133) ~[vaadin-spring-24.4.8.jar:na]
	at foo.app.service.SecurityService.logout(SecurityService.java:47) ~[classes/:na]
	at foo.app.views.MainLayout.lambda$createHeader$7a549d6b$1(MainLayout.java:88) ~[classes/:na]
	at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:239) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.component.ComponentEventBus.handleDomEvent(ComponentEventBus.java:488) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.component.ComponentEventBus.lambda$addDomTrigger$dd1b7957$1(ComponentEventBus.java:298) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.internal.nodefeature.ElementListenerMap.lambda$fireEvent$2(ElementListenerMap.java:473) ~[flow-server-24.4.8.jar:24.4.8]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) ~[na:na]
	at com.vaadin.flow.internal.nodefeature.ElementListenerMap.fireEvent(ElementListenerMap.java:473) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.server.communication.rpc.EventRpcHandler.handleNode(EventRpcHandler.java:62) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:73) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:475) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations$5(ServerRpcHandler.java:456) ~[flow-server-24.4.8.jar:24.4.8]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) ~[na:na]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:456) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:324) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.server.communication.PushHandler.lambda$new$1(PushHandler.java:165) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.server.communication.PushHandler.callWithUi(PushHandler.java:277) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.server.communication.PushHandler.onMessage(PushHandler.java:628) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.server.communication.PushAtmosphereHandler.onMessage(PushAtmosphereHandler.java:90) ~[flow-server-24.4.8.jar:24.4.8]
	at com.vaadin.flow.server.communication.PushAtmosphereHandler.onRequest(PushAtmosphereHandler.java:79) ~[flow-server-24.4.8.jar:24.4.8]
	at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:217) ~[atmosphere-runtime-3.0.5.slf4jvaadin1.jar:3.0.5.slf4jvaadin1]
	at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:103) ~[atmosphere-runtime-3.0.5.slf4jvaadin1.jar:3.0.5.slf4jvaadin1]
	at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:67) ~[atmosphere-runtime-3.0.5.slf4jvaadin1.jar:3.0.5.slf4jvaadin1]
	at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2284) ~[atmosphere-runtime-3.0.5.slf4jvaadin1.jar:3.0.5.slf4jvaadin1]
	at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:574) ~[atmosphere-runtime-3.0.5.slf4jvaadin1.jar:3.0.5.slf4jvaadin1]
	at org.atmosphere.websocket.DefaultWebSocketProcessor.lambda$dispatch$2(DefaultWebSocketProcessor.java:326) ~[atmosphere-runtime-3.0.5.slf4jvaadin1.jar:3.0.5.slf4jvaadin1]
	at org.atmosphere.util.VoidExecutorService.execute(VoidExecutorService.java:101) ~[atmosphere-runtime-3.0.5.slf4jvaadin1.jar:3.0.5.slf4jvaadin1]
	at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:323) ~[atmosphere-runtime-3.0.5.slf4jvaadin1.jar:3.0.5.slf4jvaadin1]
	at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:428) ~[atmosphere-runtime-3.0.5.slf4jvaadin1.jar:3.0.5.slf4jvaadin1]
	at org.atmosphere.container.JSR356Endpoint.lambda$onOpen$2(JSR356Endpoint.java:261) ~[atmosphere-runtime-3.0.5.slf4jvaadin1.jar:3.0.5.slf4jvaadin1]
	at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:390) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
	at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:130) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
	at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:484) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
	at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:284) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
	at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:130) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
	at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:85) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
	at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:184) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
	at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:164) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
	at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:152) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
	at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:60) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:57) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
	at java.base/java.lang.VirtualThread.run(VirtualThread.java:309) ~[na:na]

Expected behavior

Successful logout, no NPE.

Minimal reproducible example

Add a logout button and use AuthenticationContext.logout() as described here.

public class MainLayout extends AppLayout {

    private final transient AuthenticationContext authContext;

    public MainLayout(AuthenticationContext authContext) {
        this.authContext = authContext;

        H1 logo = new H1("Vaadin CRM");
        logo.addClassName("logo");
        HorizontalLayout
        header =
        authContext.getAuthenticatedUser(UserDetails.class)
                .map(user -> {
                    Button logout = new Button("Logout", click ->
                            this.authContext.logout());
                    Span loggedUser = new Span("Welcome " + user.getUsername());
                    return new HorizontalLayout(logo, loggedUser, logout);
                }).orElseGet(() -> new HorizontalLayout(logo));

        // Other page components omitted.

        addToNavbar(header);
    }
}

Versions

Hilla: 24.4.8
Flow: 24.4.8
Vaadin: 24.4.12
Copilot: 24.4.13
Copilot IDE Plugin: false
Java: Eclipse Adoptium 21.0.3
Java Hotswap: false
Frontend Hotswap: Disabled, using pre-built bundle
OS: amd64 Windows 11 10.0
Browser: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant