Browse Source

Set secure when cancelling remember-me cookie

AbstractRememberMeServices is setting remember-me cookie with checking request is secure or secure usage is independently set to a fixed flag.
But when cancelling a cookie, cookie is not being marked secure or not. It produces an inconsistency when using secure flag as a part to identity of cookie.
Onur Kağan Özcan 5 years ago
parent
commit
2015f392ef

+ 7 - 0
web/src/main/java/org/springframework/security/web/authentication/rememberme/AbstractRememberMeServices.java

@@ -53,6 +53,7 @@ import org.springframework.util.StringUtils;
  * @author Luke Taylor
  * @author Rob Winch
  * @author Eddú Meléndez
+ * @author Onur Kagan Ozcan
  * @since 2.0
  */
 public abstract class AbstractRememberMeServices implements RememberMeServices,
@@ -383,6 +384,12 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
 		if (cookieDomain != null) {
 			cookie.setDomain(cookieDomain);
 		}
+		if (useSecureCookie == null) {
+			cookie.setSecure(request.isSecure());
+		}
+		else {
+			cookie.setSecure(useSecureCookie);
+		}
 		response.addCookie(cookie);
 	}
 

+ 50 - 0
web/src/test/java/org/springframework/security/web/authentication/rememberme/AbstractRememberMeServicesTests.java

@@ -268,6 +268,56 @@ public class AbstractRememberMeServicesTests {
 		assertThat(returnedCookie.getDomain()).isEqualTo("spring.io");
 	}
 
+	@Test
+	public void cancelledCookieShouldUseSecureFlag() {
+		MockRememberMeServices services = new MockRememberMeServices(uds);
+		services.setCookieDomain("spring.io");
+		services.setUseSecureCookie(true);
+
+		MockHttpServletRequest request = new MockHttpServletRequest();
+		request.setContextPath("contextpath");
+		request.setCookies(createLoginCookie("cookie:1:2"));
+		MockHttpServletResponse response = new MockHttpServletResponse();
+
+		services.logout(request, response, Mockito.mock(Authentication.class));
+		// Try again with null Authentication
+		response = new MockHttpServletResponse();
+
+		services.logout(request, response, null);
+
+		assertCookieCancelled(response);
+
+		Cookie returnedCookie = response.getCookie(
+				AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
+		assertThat(returnedCookie.getDomain()).isEqualTo("spring.io");
+		assertThat(returnedCookie.getSecure()).isEqualTo(true);
+	}
+
+	@Test
+	public void cancelledCookieShouldUseRequestIsSecure() {
+		MockRememberMeServices services = new MockRememberMeServices(uds);
+		services.setCookieDomain("spring.io");
+
+		MockHttpServletRequest request = new MockHttpServletRequest();
+		request.setContextPath("contextpath");
+		request.setCookies(createLoginCookie("cookie:1:2"));
+		request.setSecure(true);
+		MockHttpServletResponse response = new MockHttpServletResponse();
+
+		services.logout(request, response, Mockito.mock(Authentication.class));
+		// Try again with null Authentication
+		response = new MockHttpServletResponse();
+
+		services.logout(request, response, null);
+
+		assertCookieCancelled(response);
+
+		Cookie returnedCookie = response.getCookie(
+				AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
+		assertThat(returnedCookie.getDomain()).isEqualTo("spring.io");
+		assertThat(returnedCookie.getSecure()).isEqualTo(true);
+	}
+
 	@Test(expected = CookieTheftException.class)
 	public void cookieTheftExceptionShouldBeRethrown() {
 		MockRememberMeServices services = new MockRememberMeServices(uds) {