diff --git a/flow-client/src/main/resources/META-INF/resources/frontend/form/index.ts b/flow-client/src/main/resources/META-INF/resources/frontend/form/index.ts index 9cd7af6200f..f0695723fc5 100644 --- a/flow-client/src/main/resources/META-INF/resources/frontend/form/index.ts +++ b/flow-client/src/main/resources/META-INF/resources/frontend/form/index.ts @@ -9,5 +9,5 @@ $wnd.Vaadin = $wnd.Vaadin || {}; $wnd.Vaadin.registrations = $wnd.Vaadin.registrations || []; $wnd.Vaadin.registrations.push({ is: '@vaadin/form', - version: /* updated-by-script */ '5.0-SNAPSHOT' + version: /* updated-by-script */ '6.0-SNAPSHOT' }); diff --git a/flow-server/src/main/java/com/vaadin/flow/server/connect/auth/VaadinConnectAccessChecker.java b/flow-server/src/main/java/com/vaadin/flow/server/connect/auth/VaadinConnectAccessChecker.java index 38b1f01ca36..c6faaa03e82 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/connect/auth/VaadinConnectAccessChecker.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/connect/auth/VaadinConnectAccessChecker.java @@ -16,18 +16,20 @@ package com.vaadin.flow.server.connect.auth; -import com.vaadin.flow.server.VaadinService; - import javax.annotation.security.DenyAll; import javax.annotation.security.PermitAll; import javax.annotation.security.RolesAllowed; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; - import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.vaadin.flow.server.VaadinService; + /** * Component used for checking role-based ACL in Vaadin Endpoints. *

@@ -145,8 +147,26 @@ private boolean requestForbidden(HttpServletRequest request) { return false; } - String csrfTokenInSession = (String) session.getAttribute(VaadinService.getCsrfTokenAttributeName()); - return csrfTokenInSession == null || !csrfTokenInSession.equals(request.getHeader("X-CSRF-Token")); + String csrfTokenInSession = (String) session + .getAttribute(VaadinService.getCsrfTokenAttributeName()); + if (csrfTokenInSession == null) { + if (getLogger().isInfoEnabled()) { + getLogger().info( + "Unable to verify CSRF token for endpoint request, got null token in session"); + } + + return true; + } + + if (!csrfTokenInSession.equals(request.getHeader("X-CSRF-Token"))) { + if (getLogger().isInfoEnabled()) { + getLogger().info("Invalid CSRF token in endpoint request"); + } + + return true; + } + + return false; } private boolean entityForbidden(AnnotatedElement entity, @@ -187,4 +207,8 @@ private boolean hasSecurityAnnotation(Method method) { public void enableCsrf(boolean xsrfProtectionEnabled) { this.xsrfProtectionEnabled = xsrfProtectionEnabled; } + + private static Logger getLogger() { + return LoggerFactory.getLogger(VaadinConnectAccessChecker.class); + } } diff --git a/flow-tests/test-ccdm-flow-navigation/src/main/java/com/vaadin/flow/navigate/SessionView.java b/flow-tests/test-ccdm-flow-navigation/src/main/java/com/vaadin/flow/navigate/SessionView.java new file mode 100644 index 00000000000..9682ab84b0f --- /dev/null +++ b/flow-tests/test-ccdm-flow-navigation/src/main/java/com/vaadin/flow/navigate/SessionView.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2020 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.flow.navigate; + +import com.vaadin.flow.component.Text; +import com.vaadin.flow.component.html.Div; +import com.vaadin.flow.component.html.NativeButton; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.server.VaadinSession; + +@Route(value="session") +@PageTitle("Session") +public class SessionView extends Div { + public SessionView() { + super(); + + add(new Text("Session view")); + setId("sessionView"); + + NativeButton invalidateSession = new NativeButton("Invalidate session", + event -> VaadinSession.getCurrent().getSession().invalidate()); + invalidateSession.setId("invalidateSession"); + add(invalidateSession); + } +} diff --git a/flow-tests/test-ccdm-flow-navigation/src/test/java/com/vaadin/flow/navigate/SessionViewIT.java b/flow-tests/test-ccdm-flow-navigation/src/test/java/com/vaadin/flow/navigate/SessionViewIT.java new file mode 100644 index 00000000000..a65b12b4458 --- /dev/null +++ b/flow-tests/test-ccdm-flow-navigation/src/test/java/com/vaadin/flow/navigate/SessionViewIT.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2020 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.flow.navigate; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.flow.testutil.ChromeBrowserTest; + +public class SessionViewIT extends ChromeBrowserTest { + @Test + public void indexHtmlRequestHandler_csrfToken_should_update_after_invalidateSession() { + open(); + + String originalCsrfToken = executeScript( + "return Vaadin.TypeScript.csrfToken;").toString(); + + $("button").attribute("id", "invalidateSession").waitForFirst().click(); + + open(); + String csrfToken = executeScript("return Vaadin.TypeScript.csrfToken;") + .toString(); + + Assert.assertNotEquals( + "CSRF token should update when session is invalidated", + originalCsrfToken, csrfToken); + } + + @Override + protected String getTestPath() { + return "/session"; + } +}