Skip to content

Commit 000b4bc

Browse files
lrozenblyumjzheaux
authored andcommitted
Fix NPE in HttpSecurity#addFilterBefore, HttpSecurity#addFilterAfter
Before the fix, these methods would throw a NPE in case when the filter class passed as the second parameter, is not registered yet. In particular, this exception can occur when mixing standard and custom DSL to register filters. The fix doesn't change the situation that standard DSL for registration of filters cannot refer to filters that are registered via custom DSL even though those calls were done earlier. It just provides more user-friendly error handling for this and most likely other scenarios of calls of HttpSecurity#addFilterBefore, HttpSecurity#addFilterAfter. The error handling is implemented similarly to HttpSecurity#addFilter. Closes gh-12637
1 parent aad3e61 commit 000b4bc

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -3254,7 +3254,12 @@ public HttpSecurity addFilterBefore(Filter filter, Class<? extends Filter> befor
32543254
}
32553255

32563256
private HttpSecurity addFilterAtOffsetOf(Filter filter, int offset, Class<? extends Filter> registeredFilter) {
3257-
int order = this.filterOrders.getOrder(registeredFilter) + offset;
3257+
Integer registeredFilterOrder = this.filterOrders.getOrder(registeredFilter);
3258+
if (registeredFilterOrder == null) {
3259+
throw new IllegalArgumentException(
3260+
"The Filter class " + registeredFilter.getName() + " does not have a registered order");
3261+
}
3262+
int order = registeredFilterOrder + offset;
32583263
this.filters.add(new OrderedFilter(filter, order));
32593264
this.filterOrders.put(filter.getClass(), order);
32603265
return this;

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

Lines changed: 47 additions & 1 deletion
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-2023 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.
@@ -30,6 +30,7 @@
3030
import org.junit.jupiter.api.Test;
3131
import org.junit.jupiter.api.extension.ExtendWith;
3232

33+
import org.springframework.beans.factory.UnsatisfiedDependencyException;
3334
import org.springframework.context.annotation.Bean;
3435
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
3536
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@@ -45,12 +46,29 @@
4546
import org.springframework.security.web.header.HeaderWriterFilter;
4647

4748
import static org.assertj.core.api.Assertions.assertThat;
49+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
4850

4951
@ExtendWith(SpringTestContextExtension.class)
5052
public class HttpSecurityAddFilterTest {
5153

5254
public final SpringTestContext spring = new SpringTestContext(this);
5355

56+
@Test
57+
public void addFilterAfterFilterNotRegisteredYetThenThrowIllegalArgument() {
58+
assertThatExceptionOfType(UnsatisfiedDependencyException.class)
59+
.isThrownBy(
60+
() -> this.spring.register(MyOtherFilterAfterMyFilterNotRegisteredYetConfig.class).autowire())
61+
.havingRootCause().isInstanceOf(IllegalArgumentException.class);
62+
}
63+
64+
@Test
65+
public void addFilterBeforeFilterNotRegisteredYetThenThrowIllegalArgument() {
66+
assertThatExceptionOfType(UnsatisfiedDependencyException.class)
67+
.isThrownBy(
68+
() -> this.spring.register(MyOtherFilterBeforeMyFilterNotRegisteredYetConfig.class).autowire())
69+
.havingRootCause().isInstanceOf(IllegalArgumentException.class);
70+
}
71+
5472
@Test
5573
public void addFilterAfterWhenSameFilterDifferentPlacesThenOrderCorrect() {
5674
this.spring.register(MyFilterMultipleAfterConfig.class).autowire();
@@ -209,6 +227,34 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
209227

210228
}
211229

230+
@EnableWebSecurity
231+
static class MyOtherFilterAfterMyFilterNotRegisteredYetConfig {
232+
233+
@Bean
234+
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
235+
// @formatter:off
236+
http
237+
.addFilterAfter(new MyOtherFilter(), MyFilter.class);
238+
// @formatter:on
239+
return http.build();
240+
}
241+
242+
}
243+
244+
@EnableWebSecurity
245+
static class MyOtherFilterBeforeMyFilterNotRegisteredYetConfig {
246+
247+
@Bean
248+
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
249+
// @formatter:off
250+
http
251+
.addFilterBefore(new MyOtherFilter(), MyFilter.class);
252+
// @formatter:on
253+
return http.build();
254+
}
255+
256+
}
257+
212258
@EnableWebSecurity
213259
static class MyOtherFilterRelativeToMyFilterBeforeConfig {
214260

0 commit comments

Comments
 (0)