Add Alerting About Deprecated Authorize Config

Closes gh-16213
This commit is contained in:
Max Batischev 2024-12-19 18:17:16 +03:00 committed by Josh Cummings
parent e257af8854
commit 624a8fb252
4 changed files with 76 additions and 0 deletions

View File

@ -18,10 +18,16 @@ package org.springframework.security.config.annotation.web.builders;
import java.util.List;
import jakarta.servlet.Filter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.UnreachableFilterChainException;
import org.springframework.security.web.access.intercept.AuthorizationFilter;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
/**
@ -33,11 +39,14 @@ import org.springframework.security.web.util.matcher.AnyRequestMatcher;
*/
final class WebSecurityFilterChainValidator implements FilterChainProxy.FilterChainValidator {
private final Log logger = LogFactory.getLog(getClass());
@Override
public void validate(FilterChainProxy filterChainProxy) {
List<SecurityFilterChain> chains = filterChainProxy.getFilterChains();
checkForAnyRequestRequestMatcher(chains);
checkForDuplicateMatchers(chains);
checkAuthorizationFilters(chains);
}
private void checkForAnyRequestRequestMatcher(List<SecurityFilterChain> chains) {
@ -76,4 +85,29 @@ final class WebSecurityFilterChainValidator implements FilterChainProxy.FilterCh
}
}
private void checkAuthorizationFilters(List<SecurityFilterChain> chains) {
Filter authorizationFilter = null;
Filter filterSecurityInterceptor = null;
for (SecurityFilterChain chain : chains) {
for (Filter filter : chain.getFilters()) {
if (filter instanceof AuthorizationFilter) {
authorizationFilter = filter;
}
if (filter instanceof FilterSecurityInterceptor) {
filterSecurityInterceptor = filter;
}
}
if (authorizationFilter != null && filterSecurityInterceptor != null) {
this.logger.warn(
"It is not recommended to use authorizeRequests in the configuration. Please only use authorizeHttpRequests");
}
if (filterSecurityInterceptor != null) {
this.logger.warn(
"Usage of authorizeRequests is deprecated. Please use authorizeHttpRequests in the configuration");
}
authorizationFilter = null;
filterSecurityInterceptor = null;
}
}
}

View File

@ -69,6 +69,7 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
}
checkPathOrder(new ArrayList<>(fcp.getFilterChains()));
checkForDuplicateMatchers(new ArrayList<>(fcp.getFilterChains()));
checkAuthorizationFilters(new ArrayList<>(fcp.getFilterChains()));
}
private void checkPathOrder(List<SecurityFilterChain> filterChains) {
@ -107,6 +108,31 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
}
}
private void checkAuthorizationFilters(List<SecurityFilterChain> chains) {
Filter authorizationFilter = null;
Filter filterSecurityInterceptor = null;
for (SecurityFilterChain chain : chains) {
for (Filter filter : chain.getFilters()) {
if (filter instanceof AuthorizationFilter) {
authorizationFilter = filter;
}
if (filter instanceof FilterSecurityInterceptor) {
filterSecurityInterceptor = filter;
}
}
if (authorizationFilter != null && filterSecurityInterceptor != null) {
this.logger.warn(
"It is not recommended to use authorizeRequests in the configuration. Please only use authorizeHttpRequests");
}
if (filterSecurityInterceptor != null) {
this.logger.warn(
"Usage of authorizeRequests is deprecated. Please use authorizeHttpRequests in the configuration");
}
authorizationFilter = null;
filterSecurityInterceptor = null;
}
}
@SuppressWarnings({ "unchecked" })
private <F extends Filter> F getFilter(Class<F> type, List<Filter> filters) {
for (Filter f : filters) {

View File

@ -35,6 +35,7 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException;
/**
* Tests for {@link WebSecurityFilterChainValidator}
@ -55,6 +56,15 @@ public class WebSecurityFilterChainValidatorTests {
@Mock
private FilterSecurityInterceptor authorizationInterceptor;
@Test
void validateWhenFilterSecurityInterceptorConfiguredThenValidates() {
SecurityFilterChain chain = new DefaultSecurityFilterChain(AntPathRequestMatcher.antMatcher("/api"),
this.authenticationFilter, this.exceptionTranslationFilter, this.authorizationInterceptor);
FilterChainProxy proxy = new FilterChainProxy(List.of(chain));
assertThatNoException().isThrownBy(() -> this.validator.validate(proxy));
}
@Test
void validateWhenAnyRequestMatcherIsPresentThenUnreachableFilterChainException() {
SecurityFilterChain chain1 = new DefaultSecurityFilterChain(AntPathRequestMatcher.antMatcher("/api"),

View File

@ -49,6 +49,7 @@ import org.springframework.security.web.util.matcher.AnyRequestMatcher;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willThrow;
@ -103,6 +104,11 @@ public class DefaultFilterChainValidatorTests {
ReflectionTestUtils.setField(this.validator, "logger", this.logger);
}
@Test
void validateWhenFilterSecurityInterceptorConfiguredThenValidates() {
assertThatNoException().isThrownBy(() -> this.validator.validate(this.chain));
}
// SEC-1878
@SuppressWarnings("unchecked")
@Test