You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Spring Security's CorsFilter by default uses HandlerMappingIntrospector
HandlerMappingIntrospector uses RequestAttributeChangeIgnoringWrapper which ignores all but PATH_ATTRIBUTE
RequestPredicates#restoreAttributes attempts to restore the attributes to a previous state by clearing the attribute set and then re-adding each attribute one by one
Before CorsFilter runs, MVC_RESULT_ATTRIBUTE is present in the request. When RequestPredicates#restoreAttributes is run, it removes all attributes. Then, when it tries to add the original set back in, RequestAttributeChangeIgnoringWrapper only adds PATH_ATTRIBUTE back in.
For the specific sample, the tests can be repaired by removing the CorsFilter or by exposing a custom CorsConfigurationSource bean since either of those will prevent RequestAttributeChangeIgnoringWrapper from wrapping the request.
I was also able to fix the tests by adding the following to RequestAttributeChangeIgnoringWrapper:
@OverridepublicvoidremoveAttribute(Stringname) {
if (name.equals(ServletRequestPathUtils.PATH_ATTRIBUTE) || name.equals(UrlPathHelper.PATH_ATTRIBUTE)) {
super.removeAttribute(name);
}
}
At least in this isolated case, it seems reasonable that if an attribute cannot be set, it also should not be able to be removed.
The text was updated successfully, but these errors were encountered:
Thanks for the detailed report and investigation @jzheaux. HandlerMappingIntrospector is only intended to lookup info that Spring Security needs, and the intent is to have no side effects. This why the request is wrapped but it is true that side effects can also come in the form of removals.
I will experiment with a fix that maintains an independent map of attributes at the wrapper level, which would leave the original request attributes untouched for further use after the lookup when the wrapper would no longer be in use.
rstoyanchev
changed the title
HandlerMappingIntrospector removes MockMvc's MVC_RESULT_ATTRIBUTE when combined with RouterFunctions
MockMvc's MVC_RESULT_ATTRIBUTE lost with HandlerMappingIntrospector and RouterFunctions in use
Apr 21, 2021
Related to spring-projects/spring-security-samples#9
A contributor shared the following sample application: https://github.com/hantsy/spring-webmvc-auth0-sample
The tests result in a
NullPointerException
because theMockMvc.MVC_RESULT_ATTRIBUTE
is missing.It gets removed due to the following arrangement:
CorsFilter
by default usesHandlerMappingIntrospector
HandlerMappingIntrospector
usesRequestAttributeChangeIgnoringWrapper
which ignores all butPATH_ATTRIBUTE
RequestPredicates#restoreAttributes
attempts to restore the attributes to a previous state by clearing the attribute set and then re-adding each attribute one by oneBefore
CorsFilter
runs,MVC_RESULT_ATTRIBUTE
is present in the request. WhenRequestPredicates#restoreAttributes
is run, it removes all attributes. Then, when it tries to add the original set back in,RequestAttributeChangeIgnoringWrapper
only addsPATH_ATTRIBUTE
back in.For the specific sample, the tests can be repaired by removing the
CorsFilter
or by exposing a customCorsConfigurationSource
bean since either of those will preventRequestAttributeChangeIgnoringWrapper
from wrapping the request.I was also able to fix the tests by adding the following to
RequestAttributeChangeIgnoringWrapper
:At least in this isolated case, it seems reasonable that if an attribute cannot be set, it also should not be able to be removed.
The text was updated successfully, but these errors were encountered: