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 the MockMvc.MVC_RESULT_ATTRIBUTE is missing.
HandlerExecutionChain chain = super.getHandler(request);
if (chain != null) {
DefaultMvcResult mvcResult = getMvcResult(request); // returns null
mvcResult.setHandler(chain.getHandler());
mvcResult.setInterceptors(chain.getInterceptors());
}
return chain;
It gets removed due to the following arrangement:
- 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:
@Override
public void removeAttribute(String name) {
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.
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
NullPointerExceptionbecause theMockMvc.MVC_RESULT_ATTRIBUTEis missing.It gets removed due to the following arrangement:
CorsFilterby default usesHandlerMappingIntrospectorHandlerMappingIntrospectorusesRequestAttributeChangeIgnoringWrapperwhich ignores all butPATH_ATTRIBUTERequestPredicates#restoreAttributesattempts to restore the attributes to a previous state by clearing the attribute set and then re-adding each attribute one by oneBefore
CorsFilterruns,MVC_RESULT_ATTRIBUTEis present in the request. WhenRequestPredicates#restoreAttributesis run, it removes all attributes. Then, when it tries to add the original set back in,RequestAttributeChangeIgnoringWrapperonly addsPATH_ATTRIBUTEback in.For the specific sample, the tests can be repaired by removing the
CorsFilteror by exposing a customCorsConfigurationSourcebean since either of those will preventRequestAttributeChangeIgnoringWrapperfrom 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.