diff --git a/web/src/main/java/org/springframework/security/web/session/ConcurrentSessionFilter.java b/web/src/main/java/org/springframework/security/web/session/ConcurrentSessionFilter.java index 397900a3c9..8a64e98ba0 100644 --- a/web/src/main/java/org/springframework/security/web/session/ConcurrentSessionFilter.java +++ b/web/src/main/java/org/springframework/security/web/session/ConcurrentSessionFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -141,7 +141,7 @@ public class ConcurrentSessionFilter extends GenericFilterBean { .of(() -> "Requested session ID " + request.getRequestedSessionId() + " has expired.")); doLogout(request, response); this.sessionInformationExpiredStrategy - .onExpiredSessionDetected(new SessionInformationExpiredEvent(info, request, response)); + .onExpiredSessionDetected(new SessionInformationExpiredEvent(info, request, response, chain)); return; } // Non-expired - update last request date/time diff --git a/web/src/main/java/org/springframework/security/web/session/SessionInformationExpiredEvent.java b/web/src/main/java/org/springframework/security/web/session/SessionInformationExpiredEvent.java index 925f5a0440..1fa8e1573c 100644 --- a/web/src/main/java/org/springframework/security/web/session/SessionInformationExpiredEvent.java +++ b/web/src/main/java/org/springframework/security/web/session/SessionInformationExpiredEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.security.web.session; +import jakarta.servlet.FilterChain; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -35,6 +36,8 @@ public final class SessionInformationExpiredEvent extends ApplicationEvent { private final HttpServletResponse response; + private final FilterChain filterChain; + /** * Creates a new instance * @param sessionInformation the SessionInformation that is expired @@ -43,11 +46,25 @@ public final class SessionInformationExpiredEvent extends ApplicationEvent { */ public SessionInformationExpiredEvent(SessionInformation sessionInformation, HttpServletRequest request, HttpServletResponse response) { + this(sessionInformation, request, response, null); + } + + /** + * Creates a new instance + * @param sessionInformation the SessionInformation that is expired + * @param request the HttpServletRequest + * @param response the HttpServletResponse + * @param filterChain the FilterChain + * @since 6.4 + */ + public SessionInformationExpiredEvent(SessionInformation sessionInformation, HttpServletRequest request, + HttpServletResponse response, FilterChain filterChain) { super(sessionInformation); Assert.notNull(request, "request cannot be null"); Assert.notNull(response, "response cannot be null"); this.request = request; this.response = response; + this.filterChain = filterChain; } /** @@ -68,4 +85,12 @@ public final class SessionInformationExpiredEvent extends ApplicationEvent { return (SessionInformation) getSource(); } + /** + * @return the filter chain. Can be {@code null}. + * @since 6.4 + */ + public FilterChain getFilterChain() { + return this.filterChain; + } + } diff --git a/web/src/test/java/org/springframework/security/web/session/SessionInformationExpiredEventTests.java b/web/src/test/java/org/springframework/security/web/session/SessionInformationExpiredEventTests.java index 352d6fd906..99d0cbef93 100644 --- a/web/src/test/java/org/springframework/security/web/session/SessionInformationExpiredEventTests.java +++ b/web/src/test/java/org/springframework/security/web/session/SessionInformationExpiredEventTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +20,12 @@ import java.util.Date; import org.junit.jupiter.api.Test; +import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.core.session.SessionInformation; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; /** @@ -50,4 +52,13 @@ public class SessionInformationExpiredEventTests { new SessionInformation("fake", "sessionId", new Date()), new MockHttpServletRequest(), null)); } + @Test + void constructorWhenFilterChainThenGetFilterChainReturnsNotNull() { + MockFilterChain filterChain = new MockFilterChain(); + SessionInformationExpiredEvent event = new SessionInformationExpiredEvent( + new SessionInformation("fake", "sessionId", new Date()), new MockHttpServletRequest(), + new MockHttpServletResponse(), filterChain); + assertThat(event.getFilterChain()).isSameAs(filterChain); + } + }