Adjust createNewSessionIfAllowed to prevent NPE

Ensure that isTransientAuthentication reuses the same authentication object from saveContext

Closes gh-8947
This commit is contained in:
Marcus Hert da Coregio 2021-05-26 09:03:38 -03:00
parent 9d0db200eb
commit 4d18d06d9c
2 changed files with 21 additions and 5 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -348,7 +348,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
} }
return; return;
} }
httpSession = (httpSession != null) ? httpSession : createNewSessionIfAllowed(context); httpSession = (httpSession != null) ? httpSession : createNewSessionIfAllowed(context, authentication);
// 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,8 +369,8 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
|| context.getAuthentication() != this.authBeforeExecution; || context.getAuthentication() != this.authBeforeExecution;
} }
private HttpSession createNewSessionIfAllowed(SecurityContext context) { private HttpSession createNewSessionIfAllowed(SecurityContext context, Authentication authentication) {
if (isTransientAuthentication(context.getAuthentication())) { if (isTransientAuthentication(authentication)) {
return null; return null;
} }
if (this.httpSessionExistedAtStartOfRequest) { if (this.httpSessionExistedAtStartOfRequest) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -628,6 +628,22 @@ public class HttpSessionSecurityContextRepositoryTests {
assertThat(session).isNull(); assertThat(session).isNull();
} }
// gh-8947
@Test
public void saveContextWhenSecurityContextAuthenticationUpdatedToNullThenSkipped() {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SomeOtherTransientAuthentication authentication = new SomeOtherTransientAuthentication();
repo.loadContext(holder);
SecurityContext context = mock(SecurityContext.class);
given(context.getAuthentication()).willReturn(authentication).willReturn(null);
repo.saveContext(context, holder.getRequest(), holder.getResponse());
MockHttpSession session = (MockHttpSession) request.getSession(false);
assertThat(session).isNull();
}
private SecurityContext createSecurityContext(UserDetails userDetails) { private SecurityContext createSecurityContext(UserDetails userDetails) {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails, UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails,
userDetails.getPassword(), userDetails.getAuthorities()); userDetails.getPassword(), userDetails.getAuthorities());