diff --git a/web/src/main/java/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java b/web/src/main/java/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java index 756db58a566..809606f19cc 100644 --- a/web/src/main/java/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java +++ b/web/src/main/java/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java @@ -233,6 +233,9 @@ public void setSpringSecurityContextKey(String springSecurityContextKey) { } private boolean isTransientAuthentication(Authentication authentication) { + if (authentication == null) { + return false; + } return AnnotationUtils.getAnnotation(authentication.getClass(), Transient.class) != null; } @@ -327,6 +330,9 @@ final class SaveToSessionResponseWrapper extends SaveContextOnUpdateOrErrorRespo @Override protected void saveContext(SecurityContext context) { final Authentication authentication = context.getAuthentication(); + if (isTransientAuthentication(authentication)) { + return; + } HttpSession httpSession = this.request.getSession(false); String springSecurityContextKey = HttpSessionSecurityContextRepository.this.springSecurityContextKey; // See SEC-776 @@ -370,9 +376,6 @@ private boolean contextChanged(SecurityContext context) { } private HttpSession createNewSessionIfAllowed(SecurityContext context, Authentication authentication) { - if (isTransientAuthentication(authentication)) { - return null; - } if (this.httpSessionExistedAtStartOfRequest) { this.logger.debug("HttpSession is now null, but was not null at start of request; " + "session was invalidated, so do not create a new session"); diff --git a/web/src/test/java/org/springframework/security/web/context/HttpSessionSecurityContextRepositoryTests.java b/web/src/test/java/org/springframework/security/web/context/HttpSessionSecurityContextRepositoryTests.java index cf17fe21d8f..b4d9453268f 100644 --- a/web/src/test/java/org/springframework/security/web/context/HttpSessionSecurityContextRepositoryTests.java +++ b/web/src/test/java/org/springframework/security/web/context/HttpSessionSecurityContextRepositoryTests.java @@ -21,6 +21,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.Collections; import javax.servlet.Filter; import javax.servlet.ServletException; @@ -614,6 +615,21 @@ public void saveContextWhenTransientAuthenticationSubclassThenSkipped() { assertThat(session).isNull(); } + @Test + public void saveContextWhenTransientAuthenticationAndSessionExistsThenSkipped() { + HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository(); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.getSession(); // ensure the session exists + MockHttpServletResponse response = new MockHttpServletResponse(); + HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response); + SecurityContext context = repo.loadContext(holder); + SomeTransientAuthentication authentication = new SomeTransientAuthentication(); + context.setAuthentication(authentication); + repo.saveContext(context, holder.getRequest(), holder.getResponse()); + MockHttpSession session = (MockHttpSession) request.getSession(false); + assertThat(Collections.list(session.getAttributeNames())).isEmpty(); + } + @Test public void saveContextWhenTransientAuthenticationWithCustomAnnotationThenSkipped() { HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();