Prevent Save @Transient Authentication with existing HttpSession
Previously, @Transient Authentication would get saved if an existing HttpSession existed but it shouldn't. This commit always prevents @Transient Authentication from being saved. Closes gh-9992
This commit is contained in:
parent
4318a51971
commit
96a6fef820
|
@ -233,6 +233,9 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTransientAuthentication(Authentication authentication) {
|
private boolean isTransientAuthentication(Authentication authentication) {
|
||||||
|
if (authentication == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return AnnotationUtils.getAnnotation(authentication.getClass(), Transient.class) != null;
|
return AnnotationUtils.getAnnotation(authentication.getClass(), Transient.class) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,6 +330,9 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
|
||||||
@Override
|
@Override
|
||||||
protected void saveContext(SecurityContext context) {
|
protected void saveContext(SecurityContext context) {
|
||||||
final Authentication authentication = context.getAuthentication();
|
final Authentication authentication = context.getAuthentication();
|
||||||
|
if (isTransientAuthentication(authentication)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
HttpSession httpSession = this.request.getSession(false);
|
HttpSession httpSession = this.request.getSession(false);
|
||||||
String springSecurityContextKey = HttpSessionSecurityContextRepository.this.springSecurityContextKey;
|
String springSecurityContextKey = HttpSessionSecurityContextRepository.this.springSecurityContextKey;
|
||||||
// See SEC-776
|
// See SEC-776
|
||||||
|
@ -348,7 +354,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
httpSession = (httpSession != null) ? httpSession : createNewSessionIfAllowed(context, authentication);
|
httpSession = (httpSession != null) ? httpSession : createNewSessionIfAllowed(context);
|
||||||
// If HttpSession exists, store current SecurityContext but only if it has
|
// If HttpSession exists, store current SecurityContext but only if it has
|
||||||
// actually changed in this thread (see SEC-37, SEC-1307, SEC-1528)
|
// actually changed in this thread (see SEC-37, SEC-1307, SEC-1528)
|
||||||
if (httpSession != null) {
|
if (httpSession != null) {
|
||||||
|
@ -369,10 +375,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
|
||||||
|| context.getAuthentication() != this.authBeforeExecution;
|
|| context.getAuthentication() != this.authBeforeExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpSession createNewSessionIfAllowed(SecurityContext context, Authentication authentication) {
|
private HttpSession createNewSessionIfAllowed(SecurityContext context) {
|
||||||
if (isTransientAuthentication(authentication)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (this.httpSessionExistedAtStartOfRequest) {
|
if (this.httpSessionExistedAtStartOfRequest) {
|
||||||
this.logger.debug("HttpSession is now null, but was not null at start of request; "
|
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");
|
+ "session was invalidated, so do not create a new session");
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import javax.servlet.Filter;
|
import javax.servlet.Filter;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
@ -614,6 +615,21 @@ public class HttpSessionSecurityContextRepositoryTests {
|
||||||
assertThat(session).isNull();
|
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
|
@Test
|
||||||
public void saveContextWhenTransientAuthenticationWithCustomAnnotationThenSkipped() {
|
public void saveContextWhenTransientAuthenticationWithCustomAnnotationThenSkipped() {
|
||||||
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
|
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
|
||||||
|
|
Loading…
Reference in New Issue