Skip to content

Commit 3b5d19c

Browse files
Adapt to Servlet API 6 changes and support Jakarta WebSocket 2.1
Closes gh-12146 Closes gh-12148
1 parent 9e628fb commit 3b5d19c

File tree

14 files changed

+59
-142
lines changed

14 files changed

+59
-142
lines changed

Diff for: config/spring-security-config.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ dependencies {
6363
testImplementation 'io.rsocket:rsocket-transport-netty'
6464
testImplementation 'jakarta.annotation:jakarta.annotation-api'
6565
testImplementation 'jakarta.xml.bind:jakarta.xml.bind-api'
66+
testImplementation 'jakarta.websocket:jakarta.websocket-api'
67+
testImplementation 'jakarta.websocket:jakarta.websocket-client-api'
6668
testImplementation 'ldapsdk:ldapsdk:4.1'
6769
testImplementation('net.sourceforge.htmlunit:htmlunit') {
6870
exclude group: 'commons-logging', module: 'commons-logging'

Diff for: config/src/test/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurerTests.java

-6
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,7 @@ public void whenEnableSessionUrlRewritingTrueThenEncodeNotInvoked() throws Excep
328328
HttpServletResponse responseToSpy = spy((HttpServletResponse) response);
329329
chain.doFilter(request, responseToSpy);
330330
verify(responseToSpy, atLeastOnce()).encodeRedirectURL(any());
331-
verify(responseToSpy, atLeastOnce()).encodeRedirectUrl(any());
332331
verify(responseToSpy, atLeastOnce()).encodeURL(any());
333-
verify(responseToSpy, atLeastOnce()).encodeUrl(any());
334332
})
335333
.apply(springSecurity())
336334
.build();
@@ -348,9 +346,7 @@ public void whenDefaultThenEncodeNotInvoked() throws Exception {
348346
HttpServletResponse responseToSpy = spy((HttpServletResponse) response);
349347
chain.doFilter(request, responseToSpy);
350348
verify(responseToSpy, never()).encodeRedirectURL(any());
351-
verify(responseToSpy, never()).encodeRedirectUrl(any());
352349
verify(responseToSpy, never()).encodeURL(any());
353-
verify(responseToSpy, never()).encodeUrl(any());
354350
})
355351
.apply(springSecurity())
356352
.build();
@@ -807,9 +803,7 @@ static class EncodesUrls {
807803
@RequestMapping("/")
808804
String encoded(HttpServletResponse response) {
809805
response.encodeURL("/foo");
810-
response.encodeUrl("/foo");
811806
response.encodeRedirectURL("/foo");
812-
response.encodeRedirectUrl("/foo");
813807
return "encoded";
814808
}
815809

Diff for: config/src/test/java/org/springframework/security/config/http/HttpConfigTests.java

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -149,16 +149,6 @@ public String encodeRedirectURL(String url) {
149149
throw new RuntimeException("Unexpected invocation of encodeURL");
150150
}
151151

152-
@Override
153-
public String encodeUrl(String url) {
154-
throw new RuntimeException("Unexpected invocation of encodeURL");
155-
}
156-
157-
@Override
158-
public String encodeRedirectUrl(String url) {
159-
throw new RuntimeException("Unexpected invocation of encodeURL");
160-
}
161-
162152
}
163153

164154
public static final class MockObservationRegistry implements FactoryBean<ObservationRegistry> {

Diff for: config/src/test/java/org/springframework/security/config/http/MiscHttpConfigTests.java

-14
Original file line numberDiff line numberDiff line change
@@ -578,16 +578,12 @@ public void configureWhenUsingDisableUrlRewritingAndCustomRepositoryThenRedirect
578578
FilterChainProxy proxy = this.spring.getContext().getBean(FilterChainProxy.class);
579579
proxy.doFilter(request, responseToSpy, (req, resp) -> {
580580
HttpServletResponse httpResponse = (HttpServletResponse) resp;
581-
httpResponse.encodeUrl("/");
582581
httpResponse.encodeURL("/");
583-
httpResponse.encodeRedirectUrl("/");
584582
httpResponse.encodeRedirectURL("/");
585583
httpResponse.getWriter().write("encodeRedirect");
586584
});
587585
verify(responseToSpy, never()).encodeRedirectURL(any());
588-
verify(responseToSpy, never()).encodeRedirectUrl(any());
589586
verify(responseToSpy, never()).encodeURL(any());
590-
verify(responseToSpy, never()).encodeUrl(any());
591587
assertThat(responseToSpy.getContentAsString()).isEqualTo("encodeRedirect");
592588
}
593589

@@ -1028,16 +1024,6 @@ public String encodeRedirectURL(String url) {
10281024
throw new RuntimeException("Unexpected invocation of encodeURL");
10291025
}
10301026

1031-
@Override
1032-
public String encodeUrl(String url) {
1033-
throw new RuntimeException("Unexpected invocation of encodeURL");
1034-
}
1035-
1036-
@Override
1037-
public String encodeRedirectUrl(String url) {
1038-
throw new RuntimeException("Unexpected invocation of encodeURL");
1039-
}
1040-
10411027
}
10421028

10431029
}

Diff for: config/src/test/java/org/springframework/security/config/http/SessionManagementConfigTests.java

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -620,16 +620,6 @@ public String encodeRedirectURL(String url) {
620620
throw new RuntimeException("Unexpected invocation of encodeURL");
621621
}
622622

623-
@Override
624-
public String encodeUrl(String url) {
625-
throw new RuntimeException("Unexpected invocation of encodeURL");
626-
}
627-
628-
@Override
629-
public String encodeRedirectUrl(String url) {
630-
throw new RuntimeException("Unexpected invocation of encodeURL");
631-
}
632-
633623
}
634624

635625
}

Diff for: dependencies/spring-security-dependencies.gradle

+5-3
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ dependencies {
2929
api "io.micrometer:micrometer-observation:$micrometerVersion"
3030
api "jakarta.annotation:jakarta.annotation-api:2.1.1"
3131
api "jakarta.inject:jakarta.inject-api:2.0.1"
32-
api "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:2.0.0"
32+
api "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0"
3333
api "jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.1.0"
34-
api "jakarta.servlet:jakarta.servlet-api:5.0.0"
35-
api "jakarta.xml.bind:jakarta.xml.bind-api:3.0.1"
34+
api "jakarta.servlet:jakarta.servlet-api:6.0.0"
35+
api "jakarta.xml.bind:jakarta.xml.bind-api:4.0.0"
3636
api "jakarta.persistence:jakarta.persistence-api:3.1.0"
37+
api "jakarta.websocket:jakarta.websocket-api:2.1.0"
38+
api "jakarta.websocket:jakarta.websocket-client-api:2.1.0"
3739
api "ldapsdk:ldapsdk:4.1"
3840
api "net.sourceforge.htmlunit:htmlunit:2.65.1"
3941
api "net.sourceforge.nekohtml:nekohtml:1.9.22"

Diff for: web/src/main/java/org/springframework/security/web/context/SaveContextOnUpdateOrErrorResponseWrapper.java

-16
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,6 @@ protected void onResponseCommitted() {
105105
this.contextSaved = true;
106106
}
107107

108-
@Override
109-
public final String encodeRedirectUrl(String url) {
110-
if (this.disableUrlRewriting) {
111-
return url;
112-
}
113-
return super.encodeRedirectUrl(url);
114-
}
115-
116108
@Override
117109
public final String encodeRedirectURL(String url) {
118110
if (this.disableUrlRewriting) {
@@ -121,14 +113,6 @@ public final String encodeRedirectURL(String url) {
121113
return super.encodeRedirectURL(url);
122114
}
123115

124-
@Override
125-
public final String encodeUrl(String url) {
126-
if (this.disableUrlRewriting) {
127-
return url;
128-
}
129-
return super.encodeUrl(url);
130-
}
131-
132116
@Override
133117
public final String encodeURL(String url) {
134118
if (this.disableUrlRewriting) {

Diff for: web/src/main/java/org/springframework/security/web/jackson2/CookieDeserializer.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2016 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -51,7 +51,8 @@ public Cookie deserialize(JsonParser jp, DeserializationContext ctxt) throws IOE
5151
cookie.setSecure(readJsonNode(jsonNode, "secure").asBoolean());
5252
cookie.setVersion(readJsonNode(jsonNode, "version").asInt());
5353
cookie.setPath(readJsonNode(jsonNode, "path").asText());
54-
cookie.setHttpOnly(readJsonNode(jsonNode, "httpOnly").asBoolean());
54+
JsonNode attributes = readJsonNode(jsonNode, "attributes");
55+
cookie.setHttpOnly(readJsonNode(attributes, "HttpOnly").asBoolean());
5556
return cookie;
5657
}
5758

Diff for: web/src/main/java/org/springframework/security/web/session/DisableEncodeUrlFilter.java

-10
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,11 @@ private DisableEncodeUrlResponseWrapper(HttpServletResponse response) {
6161
super(response);
6262
}
6363

64-
@Override
65-
public String encodeRedirectUrl(String url) {
66-
return url;
67-
}
68-
6964
@Override
7065
public String encodeRedirectURL(String url) {
7166
return url;
7267
}
7368

74-
@Override
75-
public String encodeUrl(String url) {
76-
return url;
77-
}
78-
7969
@Override
8070
public String encodeURL(String url) {
8171
return url;

Diff for: web/src/test/java/org/springframework/security/web/authentication/rememberme/AbstractRememberMeServicesTests.java

-22
Original file line numberDiff line numberDiff line change
@@ -362,28 +362,6 @@ public void setCookieSetsIsHttpOnlyFlagByDefault() {
362362
assertThat(cookie.isHttpOnly()).isTrue();
363363
}
364364

365-
// SEC-2791
366-
@Test
367-
public void setCookieMaxAge0VersionSet() {
368-
MockRememberMeServices services = new MockRememberMeServices();
369-
MockHttpServletRequest request = new MockHttpServletRequest();
370-
MockHttpServletResponse response = new MockHttpServletResponse();
371-
services.setCookie(new String[] { "value" }, 0, request, response);
372-
Cookie cookie = response.getCookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
373-
assertThat(cookie.getVersion()).isEqualTo(1);
374-
}
375-
376-
// SEC-2791
377-
@Test
378-
public void setCookieMaxAgeNegativeVersionSet() {
379-
MockRememberMeServices services = new MockRememberMeServices();
380-
MockHttpServletRequest request = new MockHttpServletRequest();
381-
MockHttpServletResponse response = new MockHttpServletResponse();
382-
services.setCookie(new String[] { "value" }, -1, request, response);
383-
Cookie cookie = response.getCookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
384-
assertThat(cookie.getVersion()).isEqualTo(1);
385-
}
386-
387365
// SEC-2791
388366
@Test
389367
public void setCookieMaxAge1VersionSet() {

Diff for: web/src/test/java/org/springframework/security/web/context/HttpSessionSecurityContextRepositoryTests.java

-14
Original file line numberDiff line numberDiff line change
@@ -540,21 +540,11 @@ public void sessionDisableUrlRewritingPreventsSessionIdBeingWrittenToUrl() {
540540
MockHttpServletRequest request = new MockHttpServletRequest();
541541
final String sessionId = ";jsessionid=id";
542542
MockHttpServletResponse response = new MockHttpServletResponse() {
543-
@Override
544-
public String encodeRedirectUrl(String url) {
545-
return url + sessionId;
546-
}
547-
548543
@Override
549544
public String encodeRedirectURL(String url) {
550545
return url + sessionId;
551546
}
552547

553-
@Override
554-
public String encodeUrl(String url) {
555-
return url + sessionId;
556-
}
557-
558548
@Override
559549
public String encodeURL(String url) {
560550
return url + sessionId;
@@ -563,16 +553,12 @@ public String encodeURL(String url) {
563553
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
564554
repo.loadContext(holder);
565555
String url = "/aUrl";
566-
assertThat(holder.getResponse().encodeRedirectUrl(url)).isEqualTo(url + sessionId);
567556
assertThat(holder.getResponse().encodeRedirectURL(url)).isEqualTo(url + sessionId);
568-
assertThat(holder.getResponse().encodeUrl(url)).isEqualTo(url + sessionId);
569557
assertThat(holder.getResponse().encodeURL(url)).isEqualTo(url + sessionId);
570558
repo.setDisableUrlRewriting(true);
571559
holder = new HttpRequestResponseHolder(request, response);
572560
repo.loadContext(holder);
573-
assertThat(holder.getResponse().encodeRedirectUrl(url)).isEqualTo(url);
574561
assertThat(holder.getResponse().encodeRedirectURL(url)).isEqualTo(url);
575-
assertThat(holder.getResponse().encodeUrl(url)).isEqualTo(url);
576562
assertThat(holder.getResponse().encodeURL(url)).isEqualTo(url);
577563
}
578564

Diff for: web/src/test/java/org/springframework/security/web/firewall/FirewalledResponseTests.java

+1-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -140,14 +140,6 @@ public void addCookieWhenCookieDomainContainsCrlfThenException() {
140140
.withMessageContaining(CRLF_MESSAGE);
141141
}
142142

143-
@Test
144-
public void addCookieWhenCookieCommentContainsCrlfThenException() {
145-
Cookie cookie = new Cookie("foo", "bar");
146-
cookie.setComment("foo\r\nbar");
147-
assertThatIllegalArgumentException().isThrownBy(() -> this.fwResponse.addCookie(cookie))
148-
.withMessageContaining(CRLF_MESSAGE);
149-
}
150-
151143
@Test
152144
public void rejectAnyLineEndingInNameAndValue() {
153145
validateLineEnding("foo", "foo\rbar");

Diff for: web/src/test/java/org/springframework/security/web/jackson2/CookieMixinTests.java

+46-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2016 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,19 +33,35 @@
3333
public class CookieMixinTests extends AbstractMixinTests {
3434

3535
// @formatter:off
36-
private static final String COOKIE_JSON = "{"
37-
+ "\"@class\": \"jakarta.servlet.http.Cookie\", "
38-
+ "\"name\": \"demo\", "
39-
+ "\"value\": \"cookie1\","
40-
+ "\"comment\": null, "
41-
+ "\"maxAge\": -1, "
42-
+ "\"path\": null, "
43-
+ "\"secure\": false, "
44-
+ "\"version\": 0, "
45-
+ "\"isHttpOnly\": false, "
46-
+ "\"domain\": null"
47-
+ "}";
36+
private static final String COOKIE_JSON = "{" +
37+
" \"@class\": \"jakarta.servlet.http.Cookie\"," +
38+
" \"name\": \"demo\"," +
39+
" \"value\": \"cookie1\"," +
40+
" \"attributes\":{\"@class\":\"java.util.Collections$EmptyMap\"}," +
41+
" \"comment\": null," +
42+
" \"maxAge\": -1," +
43+
" \"path\": null," +
44+
" \"secure\": false," +
45+
" \"version\": 0," +
46+
" \"domain\": null" +
47+
"}";
4848
// @formatter:on
49+
50+
// @formatter:off
51+
private static final String COOKIE_HTTP_ONLY_JSON = "{" +
52+
" \"@class\": \"jakarta.servlet.http.Cookie\"," +
53+
" \"name\": \"demo\"," +
54+
" \"value\": \"cookie1\"," +
55+
" \"attributes\":{\"@class\":\"java.util.Collections$UnmodifiableMap\", \"HttpOnly\": \"true\"}," +
56+
" \"comment\": null," +
57+
" \"maxAge\": -1," +
58+
" \"path\": null," +
59+
" \"secure\": false," +
60+
" \"version\": 0," +
61+
" \"domain\": null" +
62+
"}";
63+
// @formatter:on
64+
4965
@Test
5066
public void serializeCookie() throws JsonProcessingException, JSONException {
5167
Cookie cookie = new Cookie("demo", "cookie1");
@@ -59,7 +75,23 @@ public void deserializeCookie() throws IOException {
5975
assertThat(cookie).isNotNull();
6076
assertThat(cookie.getName()).isEqualTo("demo");
6177
assertThat(cookie.getDomain()).isEqualTo("");
62-
assertThat(cookie.isHttpOnly()).isEqualTo(false);
78+
}
79+
80+
@Test
81+
public void serializeCookieWithHttpOnly() throws JsonProcessingException, JSONException {
82+
Cookie cookie = new Cookie("demo", "cookie1");
83+
cookie.setHttpOnly(true);
84+
String actualString = this.mapper.writeValueAsString(cookie);
85+
JSONAssert.assertEquals(COOKIE_HTTP_ONLY_JSON, actualString, true);
86+
}
87+
88+
@Test
89+
public void deserializeCookieWithHttpOnly() throws IOException {
90+
Cookie cookie = this.mapper.readValue(COOKIE_HTTP_ONLY_JSON, Cookie.class);
91+
assertThat(cookie).isNotNull();
92+
assertThat(cookie.getName()).isEqualTo("demo");
93+
assertThat(cookie.getDomain()).isEqualTo("");
94+
assertThat(cookie.isHttpOnly()).isEqualTo(true);
6395
}
6496

6597
}

Diff for: web/src/test/java/org/springframework/security/web/session/DisableEncodeUrlFilterTests.java

-10
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,11 @@ void doFilterDisablesEncodeURL() throws Exception {
4646
verifyDoFilterDoesNotInteractWithResponse((httpResponse) -> httpResponse.encodeURL("/"));
4747
}
4848

49-
@Test
50-
void doFilterDisablesEncodeUrl() throws Exception {
51-
verifyDoFilterDoesNotInteractWithResponse((httpResponse) -> httpResponse.encodeUrl("/"));
52-
}
53-
5449
@Test
5550
void doFilterDisablesEncodeRedirectURL() throws Exception {
5651
verifyDoFilterDoesNotInteractWithResponse((httpResponse) -> httpResponse.encodeRedirectURL("/"));
5752
}
5853

59-
@Test
60-
void doFilterDisablesEncodeRedirectUrl() throws Exception {
61-
verifyDoFilterDoesNotInteractWithResponse((httpResponse) -> httpResponse.encodeRedirectUrl("/"));
62-
}
63-
6454
private void verifyDoFilterDoesNotInteractWithResponse(Consumer<HttpServletResponse> toInvoke) throws Exception {
6555
this.filter.doFilter(this.request, this.response, (request, response) -> {
6656
HttpServletResponse httpResponse = (HttpServletResponse) response;

0 commit comments

Comments
 (0)