Skip to content

Commit 4a9fa03

Browse files
committed
Allow Configure RequestRjectedHandler in XML
Issue gh-5007
1 parent 0483b3e commit 4a9fa03

File tree

3 files changed

+93
-2
lines changed

3 files changed

+93
-2
lines changed

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

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,19 @@
2424
import org.w3c.dom.Element;
2525

2626
import org.springframework.beans.BeanMetadataElement;
27+
import org.springframework.beans.BeansException;
2728
import org.springframework.beans.factory.config.BeanDefinition;
2829
import org.springframework.beans.factory.config.BeanReference;
30+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2931
import org.springframework.beans.factory.config.ListFactoryBean;
3032
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
3133
import org.springframework.beans.factory.config.RuntimeBeanReference;
3234
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
3335
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
36+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
3437
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
38+
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
39+
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
3540
import org.springframework.beans.factory.support.ManagedList;
3641
import org.springframework.beans.factory.support.RootBeanDefinition;
3742
import org.springframework.beans.factory.xml.BeanDefinitionParser;
@@ -393,7 +398,8 @@ else if (StringUtils.hasText(before)) {
393398
}
394399

395400
static void registerFilterChainProxyIfNecessary(ParserContext pc, Object source) {
396-
if (pc.getRegistry().containsBeanDefinition(BeanIds.FILTER_CHAIN_PROXY)) {
401+
BeanDefinitionRegistry registry = pc.getRegistry();
402+
if (registry.containsBeanDefinition(BeanIds.FILTER_CHAIN_PROXY)) {
397403
return;
398404
}
399405
// Not already registered, so register the list of filter chains and the
@@ -412,10 +418,46 @@ static void registerFilterChainProxyIfNecessary(ParserContext pc, Object source)
412418
BeanDefinition fcpBean = fcpBldr.getBeanDefinition();
413419
pc.registerBeanComponent(new BeanComponentDefinition(fcpBean,
414420
BeanIds.FILTER_CHAIN_PROXY));
415-
pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY,
421+
registry.registerAlias(BeanIds.FILTER_CHAIN_PROXY,
416422
BeanIds.SPRING_SECURITY_FILTER_CHAIN);
423+
424+
BeanDefinitionBuilder requestRejected = BeanDefinitionBuilder.rootBeanDefinition(RequestRejectedHandlerPostProcessor.class);
425+
requestRejected.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
426+
requestRejected.addConstructorArgValue("requestRejectedHandler");
427+
requestRejected.addConstructorArgValue(BeanIds.FILTER_CHAIN_PROXY);
428+
requestRejected.addConstructorArgValue("requestRejectedHandler");
429+
AbstractBeanDefinition requestRejectedBean = requestRejected.getBeanDefinition();
430+
String requestRejectedPostProcessorName = pc.getReaderContext().generateBeanName(requestRejectedBean);
431+
registry.registerBeanDefinition(requestRejectedPostProcessorName, requestRejectedBean);
432+
}
433+
434+
}
435+
436+
class RequestRejectedHandlerPostProcessor implements BeanDefinitionRegistryPostProcessor {
437+
private final String beanName;
438+
439+
private final String targetBeanName;
440+
441+
private final String targetPropertyName;
442+
443+
RequestRejectedHandlerPostProcessor(String beanName, String targetBeanName, String targetPropertyName) {
444+
this.beanName = beanName;
445+
this.targetBeanName = targetBeanName;
446+
this.targetPropertyName = targetPropertyName;
417447
}
418448

449+
@Override
450+
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
451+
if (registry.containsBeanDefinition(this.beanName)) {
452+
BeanDefinition beanDefinition = registry.getBeanDefinition(this.targetBeanName);
453+
beanDefinition.getPropertyValues().add(this.targetPropertyName, new RuntimeBeanReference(this.beanName));
454+
}
455+
}
456+
457+
@Override
458+
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
459+
460+
}
419461
}
420462

421463
class OrderDecorator implements Ordered {

config/src/test/java/org/springframework/security/config/http/MiscHttpConfigTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@
9494
import org.springframework.security.web.csrf.CsrfFilter;
9595
import org.springframework.security.web.firewall.FirewalledRequest;
9696
import org.springframework.security.web.firewall.HttpFirewall;
97+
import org.springframework.security.web.firewall.RequestRejectedException;
98+
import org.springframework.security.web.firewall.RequestRejectedHandler;
9799
import org.springframework.security.web.header.HeaderWriterFilter;
98100
import org.springframework.security.web.savedrequest.RequestCache;
99101
import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
@@ -754,6 +756,21 @@ public void reset() { }
754756
verify(firewall).getFirewalledResponse(any(HttpServletResponse.class));
755757
}
756758

759+
@Test
760+
public void getWhenUsingCustomRequestRejectedHandlerThenRequestRejectedHandlerIsInvoked() throws Exception {
761+
this.spring.configLocations(xml("RequestRejectedHandler")).autowire();
762+
763+
HttpServletResponse response = new MockHttpServletResponse();
764+
765+
RequestRejectedException rejected = new RequestRejectedException("failed");
766+
HttpFirewall firewall = this.spring.getContext().getBean(HttpFirewall.class);
767+
RequestRejectedHandler requestRejectedHandler = this.spring.getContext().getBean(RequestRejectedHandler.class);
768+
when(firewall.getFirewalledRequest(any(HttpServletRequest.class))).thenThrow(rejected);
769+
this.mvc.perform(get("/unprotected"));
770+
771+
verify(requestRejectedHandler).handle(any(), any(), any());
772+
}
773+
757774
@Test
758775
public void getWhenUsingCustomAccessDecisionManagerThenAuthorizesAccordingly() throws Exception {
759776
this.spring.configLocations(xml("CustomAccessDecisionManager")).autowire();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright 2002-2020 the original author or authors.
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ https://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
-->
17+
18+
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
19+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
20+
xmlns="http://www.springframework.org/schema/security"
21+
xsi:schemaLocation="
22+
http://www.springframework.org/schema/security
23+
https://www.springframework.org/schema/security/spring-security.xsd
24+
http://www.springframework.org/schema/beans
25+
https://www.springframework.org/schema/beans/spring-beans.xsd">
26+
27+
<b:import resource="MiscHttpConfigTests-HttpFirewall.xml"/>
28+
29+
<b:bean id="requestRejectedHandler" class="org.mockito.Mockito" factory-method="mock">
30+
<b:constructor-arg value="org.springframework.security.web.firewall.RequestRejectedHandler"/>
31+
</b:bean>
32+
</b:beans>

0 commit comments

Comments
 (0)