Skip to content

Commit 39b0620

Browse files
committed
Add DisableUrlRewritingFilter
Closes gh-11084
1 parent 32b83aa commit 39b0620

File tree

14 files changed

+375
-36
lines changed

14 files changed

+375
-36
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/HttpSecurityBuilder.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
4343
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
4444
import org.springframework.security.web.session.ConcurrentSessionFilter;
45+
import org.springframework.security.web.session.DisableEncodeUrlFilter;
4546
import org.springframework.security.web.session.SessionManagementFilter;
4647

4748
/**
@@ -124,6 +125,7 @@ public interface HttpSecurityBuilder<H extends HttpSecurityBuilder<H>>
124125
* The ordering of the Filters is:
125126
*
126127
* <ul>
128+
* <li>{@link DisableEncodeUrlFilter}</li>
127129
* <li>{@link ChannelProcessingFilter}</li>
128130
* <li>{@link SecurityContextPersistenceFilter}</li>
129131
* <li>{@link LogoutFilter}</li>

config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
4747
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
4848
import org.springframework.security.web.session.ConcurrentSessionFilter;
49+
import org.springframework.security.web.session.DisableEncodeUrlFilter;
4950
import org.springframework.security.web.session.SessionManagementFilter;
5051
import org.springframework.web.filter.CorsFilter;
5152

@@ -68,6 +69,7 @@ final class FilterOrderRegistration {
6869

6970
FilterOrderRegistration() {
7071
Step order = new Step(INITIAL_ORDER, ORDER_STEP);
72+
put(DisableEncodeUrlFilter.class, order.next());
7173
put(ChannelProcessingFilter.class, order.next());
7274
order.next(); // gh-8105
7375
put(WebAsyncManagerIntegrationFilter.class, order.next());

config/src/main/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurer.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import org.springframework.security.web.savedrequest.NullRequestCache;
5353
import org.springframework.security.web.savedrequest.RequestCache;
5454
import org.springframework.security.web.session.ConcurrentSessionFilter;
55+
import org.springframework.security.web.session.DisableEncodeUrlFilter;
5556
import org.springframework.security.web.session.InvalidSessionStrategy;
5657
import org.springframework.security.web.session.SessionInformationExpiredStrategy;
5758
import org.springframework.security.web.session.SessionManagementFilter;
@@ -376,6 +377,9 @@ public void configure(H http) {
376377
concurrentSessionFilter = postProcess(concurrentSessionFilter);
377378
http.addFilter(concurrentSessionFilter);
378379
}
380+
if (!this.enableSessionUrlRewriting) {
381+
http.addFilter(new DisableEncodeUrlFilter());
382+
}
379383
}
380384

381385
private ConcurrentSessionFilter createConcurrencyFilter(H http) {

config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
6969
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
7070
import org.springframework.security.web.session.ConcurrentSessionFilter;
71+
import org.springframework.security.web.session.DisableEncodeUrlFilter;
7172
import org.springframework.security.web.session.SessionManagementFilter;
7273
import org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy;
7374
import org.springframework.security.web.session.SimpleRedirectSessionInformationExpiredStrategy;
@@ -179,6 +180,8 @@ class HttpConfigurationBuilder {
179180

180181
private BeanDefinition csrfFilter;
181182

183+
private BeanDefinition disableUrlRewriteFilter;
184+
182185
private BeanDefinition wellKnownChangePasswordRedirectFilter;
183186

184187
private BeanMetadataElement csrfLogoutHandler;
@@ -204,6 +207,7 @@ class HttpConfigurationBuilder {
204207
String createSession = element.getAttribute(ATT_CREATE_SESSION);
205208
this.sessionPolicy = !StringUtils.hasText(createSession) ? SessionCreationPolicy.IF_REQUIRED
206209
: createPolicy(createSession);
210+
createDisableEncodeUrlFilter();
207211
createCsrfFilter();
208212
createSecurityPersistence();
209213
createSessionManagementFilters();
@@ -319,10 +323,6 @@ private void createSecurityContextPersistenceFilter() {
319323

320324
private void createSecurityContextRepository() {
321325
String repoRef = this.httpElt.getAttribute(ATT_SECURITY_CONTEXT_REPOSITORY);
322-
String disableUrlRewriting = this.httpElt.getAttribute(ATT_DISABLE_URL_REWRITING);
323-
if (!StringUtils.hasText(disableUrlRewriting)) {
324-
disableUrlRewriting = "true";
325-
}
326326
if (!StringUtils.hasText(repoRef)) {
327327
BeanDefinitionBuilder contextRepo;
328328
if (this.sessionPolicy == SessionCreationPolicy.STATELESS) {
@@ -340,7 +340,7 @@ private void createSecurityContextRepository() {
340340
default:
341341
contextRepo.addPropertyValue("allowSessionCreation", Boolean.TRUE);
342342
}
343-
if ("true".equals(disableUrlRewriting)) {
343+
if (isDisableUrlRewriting()) {
344344
contextRepo.addPropertyValue("disableUrlRewriting", Boolean.TRUE);
345345
}
346346
}
@@ -352,6 +352,11 @@ private void createSecurityContextRepository() {
352352
this.contextRepoRef = new RuntimeBeanReference(repoRef);
353353
}
354354

355+
private boolean isDisableUrlRewriting() {
356+
String disableUrlRewriting = this.httpElt.getAttribute(ATT_DISABLE_URL_REWRITING);
357+
return !"false".equals(disableUrlRewriting);
358+
}
359+
355360
private void createSecurityContextHolderFilter() {
356361
BeanDefinitionBuilder filter = BeanDefinitionBuilder.rootBeanDefinition(SecurityContextHolderFilter.class);
357362
filter.addConstructorArgValue(this.contextRepoRef);
@@ -718,6 +723,12 @@ private void createCorsFilter() {
718723

719724
}
720725

726+
private void createDisableEncodeUrlFilter() {
727+
if (isDisableUrlRewriting()) {
728+
this.disableUrlRewriteFilter = new RootBeanDefinition(DisableEncodeUrlFilter.class);
729+
}
730+
}
731+
721732
private void createCsrfFilter() {
722733
Element elmt = DomUtils.getChildElementByTagName(this.httpElt, Elements.CSRF);
723734
this.csrfParser = new CsrfBeanDefinitionParser();
@@ -757,6 +768,9 @@ BeanReference getRequestCache() {
757768

758769
List<OrderDecorator> getFilters() {
759770
List<OrderDecorator> filters = new ArrayList<>();
771+
if (this.disableUrlRewriteFilter != null) {
772+
filters.add(new OrderDecorator(this.disableUrlRewriteFilter, SecurityFilters.DISABLE_ENCODE_URL_FILTER));
773+
}
760774
if (this.cpf != null) {
761775
filters.add(new OrderDecorator(this.cpf, SecurityFilters.CHANNEL_FILTER));
762776
}

config/src/main/java/org/springframework/security/config/http/SecurityFilters.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ enum SecurityFilters {
2929

3030
FIRST(Integer.MIN_VALUE),
3131

32+
DISABLE_ENCODE_URL_FILTER,
33+
3234
CHANNEL_FILTER,
3335

3436
SECURITY_CONTEXT_FILTER,

config/src/main/resources/org/springframework/security/config/spring-security-5.7.rnc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1318,4 +1318,4 @@ position =
13181318
## The explicit position at which the custom-filter should be placed in the chain. Use if you are replacing a standard filter.
13191319
attribute position {named-security-filter}
13201320

1321-
named-security-filter = "FIRST" | "CHANNEL_FILTER" | "SECURITY_CONTEXT_FILTER" | "CONCURRENT_SESSION_FILTER" | "WEB_ASYNC_MANAGER_FILTER" | "HEADERS_FILTER" | "CORS_FILTER" | "SAML2_LOGOUT_REQUEST_FILTER" | "SAML2_LOGOUT_RESPONSE_FILTER" | "CSRF_FILTER" | "SAML2_LOGOUT_FILTER" | "LOGOUT_FILTER" | "OAUTH2_AUTHORIZATION_REQUEST_FILTER" | "SAML2_AUTHENTICATION_REQUEST_FILTER" | "X509_FILTER" | "PRE_AUTH_FILTER" | "CAS_FILTER" | "OAUTH2_LOGIN_FILTER" | "SAML2_AUTHENTICATION_FILTER" | "FORM_LOGIN_FILTER" | "OPENID_FILTER" | "LOGIN_PAGE_FILTER" |"LOGOUT_PAGE_FILTER" | "DIGEST_AUTH_FILTER" | "BEARER_TOKEN_AUTH_FILTER" | "BASIC_AUTH_FILTER" | "REQUEST_CACHE_FILTER" | "SERVLET_API_SUPPORT_FILTER" | "JAAS_API_SUPPORT_FILTER" | "REMEMBER_ME_FILTER" | "ANONYMOUS_FILTER" | "OAUTH2_AUTHORIZATION_CODE_GRANT_FILTER" | "WELL_KNOWN_CHANGE_PASSWORD_REDIRECT_FILTER" | "SESSION_MANAGEMENT_FILTER" | "EXCEPTION_TRANSLATION_FILTER" | "FILTER_SECURITY_INTERCEPTOR" | "SWITCH_USER_FILTER" | "LAST"
1321+
named-security-filter = "FIRST" | "DISABLE_ENCODE_URL_FILTER" | "CHANNEL_FILTER" | "SECURITY_CONTEXT_FILTER" | "CONCURRENT_SESSION_FILTER" | "WEB_ASYNC_MANAGER_FILTER" | "HEADERS_FILTER" | "CORS_FILTER" | "SAML2_LOGOUT_REQUEST_FILTER" | "SAML2_LOGOUT_RESPONSE_FILTER" | "CSRF_FILTER" | "SAML2_LOGOUT_FILTER" | "LOGOUT_FILTER" | "OAUTH2_AUTHORIZATION_REQUEST_FILTER" | "SAML2_AUTHENTICATION_REQUEST_FILTER" | "X509_FILTER" | "PRE_AUTH_FILTER" | "CAS_FILTER" | "OAUTH2_LOGIN_FILTER" | "SAML2_AUTHENTICATION_FILTER" | "FORM_LOGIN_FILTER" | "OPENID_FILTER" | "LOGIN_PAGE_FILTER" |"LOGOUT_PAGE_FILTER" | "DIGEST_AUTH_FILTER" | "BEARER_TOKEN_AUTH_FILTER" | "BASIC_AUTH_FILTER" | "REQUEST_CACHE_FILTER" | "SERVLET_API_SUPPORT_FILTER" | "JAAS_API_SUPPORT_FILTER" | "REMEMBER_ME_FILTER" | "ANONYMOUS_FILTER" | "OAUTH2_AUTHORIZATION_CODE_GRANT_FILTER" | "WELL_KNOWN_CHANGE_PASSWORD_REDIRECT_FILTER" | "SESSION_MANAGEMENT_FILTER" | "EXCEPTION_TRANSLATION_FILTER" | "FILTER_SECURITY_INTERCEPTOR" | "SWITCH_USER_FILTER" | "LAST"

config/src/main/resources/org/springframework/security/config/spring-security-5.7.xsd

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
</xs:annotation>
125125
<xs:complexType/>
126126
</xs:element>
127-
127+
128128
<xs:attributeGroup name="password-encoder.attlist">
129129
<xs:attribute name="ref" type="xs:token">
130130
<xs:annotation>
@@ -408,7 +408,7 @@
408408
</xs:annotation>
409409
</xs:attribute>
410410
</xs:attributeGroup>
411-
411+
412412
<xs:attributeGroup name="ldap-ap.attlist">
413413
<xs:attribute name="server-ref" type="xs:token">
414414
<xs:annotation>
@@ -488,7 +488,7 @@
488488
</xs:annotation>
489489
</xs:attribute>
490490
</xs:attributeGroup>
491-
491+
492492
<xs:attributeGroup name="password-compare.attlist">
493493
<xs:attribute name="password-attribute" type="xs:token">
494494
<xs:annotation>
@@ -541,7 +541,7 @@
541541
</xs:annotation>
542542
</xs:attribute>
543543
</xs:attributeGroup>
544-
544+
545545
<xs:attributeGroup name="protect.attlist">
546546
<xs:attribute name="method" use="required" type="xs:token">
547547
<xs:annotation>
@@ -842,13 +842,13 @@
842842
</xs:annotation>
843843
</xs:attribute>
844844
</xs:attributeGroup>
845-
846-
847-
848-
849-
850-
851-
845+
846+
847+
848+
849+
850+
851+
852852
<xs:attributeGroup name="protect-pointcut.attlist">
853853
<xs:attribute name="expression" use="required" type="xs:string">
854854
<xs:annotation>
@@ -1323,7 +1323,7 @@
13231323
</xs:annotation>
13241324
</xs:attribute>
13251325
</xs:attributeGroup>
1326-
1326+
13271327
<xs:attributeGroup name="access-denied-handler.attlist">
13281328
<xs:attribute name="ref" type="xs:token">
13291329
<xs:annotation>
@@ -1348,7 +1348,7 @@
13481348
</xs:annotation>
13491349
</xs:attribute>
13501350
</xs:attributeGroup>
1351-
1351+
13521352
<xs:attributeGroup name="intercept-url.attlist">
13531353
<xs:attribute name="pattern" type="xs:token">
13541354
<xs:annotation>
@@ -1405,7 +1405,7 @@
14051405
</xs:annotation>
14061406
</xs:attribute>
14071407
</xs:attributeGroup>
1408-
1408+
14091409
<xs:attributeGroup name="logout.attlist">
14101410
<xs:attribute name="logout-url" type="xs:token">
14111411
<xs:annotation>
@@ -1452,7 +1452,7 @@
14521452
<xs:attributeGroup ref="security:ref"/>
14531453
</xs:complexType>
14541454
</xs:element>
1455-
1455+
14561456
<xs:attributeGroup name="form-login.attlist">
14571457
<xs:attribute name="login-processing-url" type="xs:token">
14581458
<xs:annotation>
@@ -1967,7 +1967,7 @@
19671967
</xs:annotation>
19681968
</xs:attribute>
19691969
</xs:attributeGroup>
1970-
1970+
19711971
<xs:element name="attribute-exchange">
19721972
<xs:annotation>
19731973
<xs:documentation>Sets up an attribute exchange configuration to request specified attributes from the
@@ -2034,7 +2034,7 @@
20342034
</xs:annotation>
20352035
</xs:attribute>
20362036
</xs:attributeGroup>
2037-
2037+
20382038
<xs:attributeGroup name="saml2-login.attlist">
20392039
<xs:attribute name="relying-party-registration-repository-ref" type="xs:token">
20402040
<xs:annotation>
@@ -2091,7 +2091,7 @@
20912091
</xs:annotation>
20922092
</xs:attribute>
20932093
</xs:attributeGroup>
2094-
2094+
20952095
<xs:attributeGroup name="saml2-logout.attlist">
20962096
<xs:attribute name="logout-url" type="xs:token">
20972097
<xs:annotation>
@@ -2544,7 +2544,7 @@
25442544
</xs:simpleType>
25452545
</xs:attribute>
25462546
</xs:attributeGroup>
2547-
2547+
25482548
<xs:attributeGroup name="http-basic.attlist">
25492549
<xs:attribute name="entry-point-ref" type="xs:token">
25502550
<xs:annotation>
@@ -2577,7 +2577,7 @@
25772577
</xs:annotation>
25782578
</xs:attribute>
25792579
</xs:attributeGroup>
2580-
2580+
25812581
<xs:attributeGroup name="session-management.attlist">
25822582
<xs:attribute name="session-fixation-protection">
25832583
<xs:annotation>
@@ -2633,7 +2633,7 @@
26332633
</xs:annotation>
26342634
</xs:attribute>
26352635
</xs:attributeGroup>
2636-
2636+
26372637
<xs:attributeGroup name="concurrency-control.attlist">
26382638
<xs:attribute name="max-sessions" type="xs:token">
26392639
<xs:annotation>
@@ -2680,7 +2680,7 @@
26802680
</xs:annotation>
26812681
</xs:attribute>
26822682
</xs:attributeGroup>
2683-
2683+
26842684
<xs:attributeGroup name="remember-me.attlist">
26852685
<xs:attribute name="key" type="xs:token">
26862686
<xs:annotation>
@@ -2778,7 +2778,7 @@
27782778
<xs:attributeGroup name="remember-me-data-source-ref">
27792779
<xs:attributeGroup ref="security:data-source-ref"/>
27802780
</xs:attributeGroup>
2781-
2781+
27822782
<xs:attributeGroup name="anonymous.attlist">
27832783
<xs:attribute name="key" type="xs:token">
27842784
<xs:annotation>
@@ -2811,8 +2811,8 @@
28112811
</xs:annotation>
28122812
</xs:attribute>
28132813
</xs:attributeGroup>
2814-
2815-
2814+
2815+
28162816
<xs:attributeGroup name="http-port">
28172817
<xs:attribute name="http" use="required" type="xs:token">
28182818
<xs:annotation>
@@ -2829,7 +2829,7 @@
28292829
</xs:annotation>
28302830
</xs:attribute>
28312831
</xs:attributeGroup>
2832-
2832+
28332833
<xs:attributeGroup name="x509.attlist">
28342834
<xs:attribute name="subject-principal-regex" type="xs:token">
28352835
<xs:annotation>
@@ -2966,7 +2966,7 @@
29662966
</xs:annotation>
29672967
</xs:attribute>
29682968
</xs:attributeGroup>
2969-
2969+
29702970
<xs:attributeGroup name="ap.attlist">
29712971
<xs:attribute name="ref" type="xs:token">
29722972
<xs:annotation>
@@ -3018,7 +3018,7 @@
30183018
</xs:annotation>
30193019
</xs:attribute>
30203020
</xs:attributeGroup>
3021-
3021+
30223022
<xs:attributeGroup name="user.attlist">
30233023
<xs:attribute name="name" use="required" type="xs:token">
30243024
<xs:annotation>
@@ -3720,6 +3720,7 @@
37203720
<xs:simpleType name="named-security-filter">
37213721
<xs:restriction base="xs:token">
37223722
<xs:enumeration value="FIRST"/>
3723+
<xs:enumeration value="DISABLE_ENCODE_URL_FILTER"/>
37233724
<xs:enumeration value="CHANNEL_FILTER"/>
37243725
<xs:enumeration value="SECURITY_CONTEXT_FILTER"/>
37253726
<xs:enumeration value="CONCURRENT_SESSION_FILTER"/>
@@ -3759,4 +3760,4 @@
37593760
<xs:enumeration value="LAST"/>
37603761
</xs:restriction>
37613762
</xs:simpleType>
3762-
</xs:schema>
3763+
</xs:schema>

config/src/test/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistrationTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public void putWhenCustomFilterAlreadyExistsThenDoesNotOverride() {
5353

5454
@Test
5555
public void putWhenPredefinedFilterThenDoesNotOverride() {
56-
int position = 100;
56+
int position = 200;
5757
Integer predefinedFilterOrderBefore = this.filterOrderRegistration.getOrder(ChannelProcessingFilter.class);
5858
this.filterOrderRegistration.put(MyFilter.class, position);
5959
Integer myFilterOrder = this.filterOrderRegistration.getOrder(MyFilter.class);

0 commit comments

Comments
 (0)