Description
Describe the bug
When the ErrorPageSecurityFilter
kicks in, it uses the DefaultWebInvocationPrivilegeEvaluator
to determine if some error pages should be shown or if just a status code should be sent. If the pattern controlling access to error pages contain patterns based on remote address, the invocation fails with an exception:
java.lang.UnsupportedOperationException: public abstract java.lang.String javax.servlet.ServletRequest.getRemoteAddr() is not supported
at org.springframework.security.web.FilterInvocation$UnsupportedOperationExceptionInvocationHandler.invoke(FilterInvocation.java:326) ~[spring-security-web-5.6.1.jar:5.6.1]
at com.sun.proxy.$Proxy68.getRemoteAddr(Unknown Source) ~[na:na]
at javax.servlet.ServletRequestWrapper.getRemoteAddr(ServletRequestWrapper.java:241) ~[tomcat-embed-core-9.0.56.jar:4.0.FR]
at org.springframework.security.web.util.matcher.IpAddressMatcher.matches(IpAddressMatcher.java:65) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.expression.WebSecurityExpressionRoot.hasIpAddress(WebSecurityExpressionRoot.java:51) ~[spring-security-web-5.6.1.jar:5.6.1]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:129) ~[spring-expression-5.3.14.jar:5.3.14]
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:139) ~[spring-expression-5.3.14.jar:5.3.14]
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:95) ~[spring-expression-5.3.14.jar:5.3.14]
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:117) ~[spring-expression-5.3.14.jar:5.3.14]
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:308) ~[spring-expression-5.3.14.jar:5.3.14]
at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:30) ~[spring-security-core-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.expression.WebExpressionVoter.vote(WebExpressionVoter.java:59) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.expression.WebExpressionVoter.vote(WebExpressionVoter.java:39) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:60) ~[spring-security-core-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator.isAllowed(DefaultWebInvocationPrivilegeEvaluator.java:100) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator.isAllowed(DefaultWebInvocationPrivilegeEvaluator.java:67) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.boot.web.servlet.filter.ErrorPageSecurityFilter.isAllowed(ErrorPageSecurityFilter.java:84) ~[spring-boot-2.6.2.jar:2.6.2]
at org.springframework.boot.web.servlet.filter.ErrorPageSecurityFilter.doFilter(ErrorPageSecurityFilter.java:72) ~[spring-boot-2.6.2.jar:2.6.2]
....
To Reproduce
-
Download project https://github.com/fast-reflexes/spring-boot-bug/tree/getRemoteAddrNotImplemented
It is a project with the following security config:override fun configure(http: HttpSecurity) { http .authorizeRequests() .antMatchers("/error/**").hasIpAddress("127.0.0.1") .antMatchers("/non-existing/**").denyAll() .antMatchers("/test/**", "/favicon.ico").permitAll() .anyRequest().denyAll() }
-
Start the app with
./gradlew bootRun
-
Access
localhost:8080/non-existing
-
Check exception in console
Expected behavior
Expected behaviour is to either allow access to the Spring error page or to just send a status code, depending on the remote address pattern and remote address itself. Definitely not an exception and downgrading to the Tomcat error page.
Sample
See above