@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
/ *
* Copyright 2002 - 201 2 the original author or authors .
* Copyright 2002 - 2020 the original author or authors .
*
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
@ -15,12 +15,19 @@
@@ -15,12 +15,19 @@
* /
package org.springframework.security.config.http ;
import java.util.Arrays ;
import java.util.HashSet ;
import java.util.List ;
import javax.servlet.http.HttpServletRequest ;
import org.w3c.dom.Element ;
import org.springframework.beans.BeanMetadataElement ;
import org.springframework.beans.factory.config.BeanDefinition ;
import org.springframework.beans.factory.config.RuntimeBeanReference ;
import org.springframework.beans.factory.parsing.BeanComponentDefinition ;
import org.springframework.beans.factory.support.BeanDefinitionBuilder ;
import org.springframework.beans.factory.support.ManagedList ;
import org.springframework.beans.factory.support.ManagedMap ;
import org.springframework.beans.factory.support.RootBeanDefinition ;
import org.springframework.beans.factory.xml.BeanDefinitionParser ;
@ -38,6 +45,10 @@ import org.springframework.security.web.csrf.MissingCsrfTokenException;
@@ -38,6 +45,10 @@ import org.springframework.security.web.csrf.MissingCsrfTokenException;
import org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor ;
import org.springframework.security.web.session.InvalidSessionAccessDeniedHandler ;
import org.springframework.security.web.session.InvalidSessionStrategy ;
import org.springframework.security.web.util.matcher.AndRequestMatcher ;
import org.springframework.security.web.util.matcher.NegatedRequestMatcher ;
import org.springframework.security.web.util.matcher.OrRequestMatcher ;
import org.springframework.security.web.util.matcher.RequestMatcher ;
import org.springframework.util.ClassUtils ;
import org.springframework.util.StringUtils ;
@ -58,6 +69,8 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
@@ -58,6 +69,8 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
private String csrfRepositoryRef ;
private BeanDefinition csrfFilter ;
private String requestMatcherRef ;
@Override
public BeanDefinition parse ( Element element , ParserContext pc ) {
boolean disabled = element ! = null
@ -77,10 +90,9 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
@@ -77,10 +90,9 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
}
}
String matcherRef = null ;
if ( element ! = null ) {
this . csrfRepositoryRef = element . getAttribute ( ATT_REPOSITORY ) ;
m atcherRef = element . getAttribute ( ATT_MATCHER ) ;
this . requestM atcherRef = element . getAttribute ( ATT_MATCHER ) ;
}
if ( ! StringUtils . hasText ( this . csrfRepositoryRef ) ) {
@ -100,8 +112,8 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
@@ -100,8 +112,8 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
. rootBeanDefinition ( CsrfFilter . class ) ;
builder . addConstructorArgReference ( this . csrfRepositoryRef ) ;
if ( StringUtils . hasText ( m atcherRef) ) {
builder . addPropertyReference ( "requireCsrfProtectionMatcher" , m atcherRef) ;
if ( StringUtils . hasText ( this . requestM atcherRef) ) {
builder . addPropertyReference ( "requireCsrfProtectionMatcher" , this . requestM atcherRef) ;
}
this . csrfFilter = builder . getBeanDefinition ( ) ;
@ -172,4 +184,46 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
@@ -172,4 +184,46 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
csrfAuthenticationStrategy . addConstructorArgReference ( this . csrfRepositoryRef ) ;
return csrfAuthenticationStrategy . getBeanDefinition ( ) ;
}
void setIgnoreCsrfRequestMatchers ( List < BeanDefinition > requestMatchers ) {
if ( ! requestMatchers . isEmpty ( ) ) {
BeanMetadataElement requestMatcher ;
if ( StringUtils . hasText ( this . requestMatcherRef ) ) {
requestMatcher = new RuntimeBeanReference ( this . requestMatcherRef ) ;
} else {
requestMatcher = new RootBeanDefinition ( DefaultRequiresCsrfMatcher . class ) ;
}
BeanDefinitionBuilder and = BeanDefinitionBuilder
. rootBeanDefinition ( AndRequestMatcher . class ) ;
BeanDefinitionBuilder negated = BeanDefinitionBuilder
. rootBeanDefinition ( NegatedRequestMatcher . class ) ;
BeanDefinitionBuilder or = BeanDefinitionBuilder
. rootBeanDefinition ( OrRequestMatcher . class ) ;
or . addConstructorArgValue ( requestMatchers ) ;
negated . addConstructorArgValue ( or . getBeanDefinition ( ) ) ;
List < BeanMetadataElement > ands = new ManagedList < > ( ) ;
ands . add ( requestMatcher ) ;
ands . add ( negated . getBeanDefinition ( ) ) ;
and . addConstructorArgValue ( ands ) ;
this . csrfFilter . getPropertyValues ( )
. add ( "requireCsrfProtectionMatcher" , and . getBeanDefinition ( ) ) ;
}
}
private static final class DefaultRequiresCsrfMatcher implements RequestMatcher {
private final HashSet < String > allowedMethods = new HashSet < > (
Arrays . asList ( "GET" , "HEAD" , "TRACE" , "OPTIONS" ) ) ;
/ *
* ( non - Javadoc )
*
* @see
* org . springframework . security . web . util . matcher . RequestMatcher # matches ( javax .
* servlet . http . HttpServletRequest )
* /
@Override
public boolean matches ( HttpServletRequest request ) {
return ! this . allowedMethods . contains ( request . getMethod ( ) ) ;
}
}
}