From ad0d3e97020e28750f8ee3bd657dc62da02fdb2d Mon Sep 17 00:00:00 2001 From: Eleftheria Stein Date: Tue, 27 Aug 2019 15:17:40 -0400 Subject: [PATCH] Polish remember me username check --- .../TokenBasedRememberMeServices.java | 8 ++++---- .../TokenBasedRememberMeServicesTests.java | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/web/src/main/java/org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServices.java b/web/src/main/java/org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServices.java index 634c9eb632..2d7ff3399d 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServices.java +++ b/web/src/main/java/org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServices.java @@ -21,6 +21,7 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.codec.Hex; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.codec.Utf8; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; @@ -123,10 +124,9 @@ public class TokenBasedRememberMeServices extends AbstractRememberMeServices { UserDetails userDetails = getUserDetailsService().loadUserByUsername( cookieTokens[0]); - if (userDetails == null) { - throw new InvalidCookieException("Cookie token[0] contained username '" - + cookieTokens[0] + "' that does not exist."); - } + Assert.notNull(userDetails, () -> "UserDetailsService " + getUserDetailsService() + + " returned null for username " + cookieTokens[0] + ". " + + "This is an interface contract violation"); // Check signature of token matches remaining details. // Must do this after user lookup, as we need the DAO-derived password. diff --git a/web/src/test/java/org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServicesTests.java b/web/src/test/java/org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServicesTests.java index 2df01cbca5..f7cf7a8248 100644 --- a/web/src/test/java/org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServicesTests.java +++ b/web/src/test/java/org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServicesTests.java @@ -69,6 +69,10 @@ public class TokenBasedRememberMeServicesTests { new UsernameNotFoundException("")); } + void udsWillReturnNull() { + when(uds.loadUserByUsername(any(String.class))).thenReturn(null); + } + private long determineExpiryTimeFromBased64EncodedToken(String validToken) { String cookieAsPlainText = new String(Base64.decodeBase64(validToken.getBytes())); String[] cookieTokens = StringUtils.delimitedListToStringArray(cookieAsPlainText, @@ -230,6 +234,21 @@ public class TokenBasedRememberMeServicesTests { assertThat(returnedCookie.getMaxAge()).isZero(); } + @Test(expected = IllegalArgumentException.class) + public void autoLoginClearsCookieIfUserServiceMisconfigured() { + udsWillReturnNull(); + Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, + generateCorrectCookieContentForToken( + System.currentTimeMillis() + 1000000, "someone", "password", + "key")); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setCookies(cookie); + + MockHttpServletResponse response = new MockHttpServletResponse(); + + services.autoLogin(request, response); + } + @Test public void autoLoginWithValidTokenAndUserSucceeds() throws Exception { udsWillReturnUser();