Skip to content

MockMvc's MVC_RESULT_ATTRIBUTE lost with HandlerMappingIntrospector and RouterFunctions in use #26833

Closed
@jzheaux

Description

@jzheaux

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.

Metadata

Metadata

Assignees

Labels

in: testIssues in the test modulein: webIssues in web modules (web, webmvc, webflux, websocket)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions