-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Description
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
CorsFilterby default usesHandlerMappingIntrospector HandlerMappingIntrospectorusesRequestAttributeChangeIgnoringWrapperwhich 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 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.