Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
jzheaux opened this issue Apr 20, 2021 · 2 comments
Assignees
Labels
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@jzheaux
Copy link
Contributor

jzheaux commented Apr 20, 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 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.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Apr 20, 2021
@sbrannen sbrannen added in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) labels Apr 21, 2021
@sbrannen
Copy link
Member

See also: discussion on Stack Overflow

@rstoyanchev
Copy link
Contributor

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 rstoyanchev added this to the 5.3.7 milestone Apr 21, 2021
@rstoyanchev rstoyanchev added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Apr 21, 2021
@rstoyanchev 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
Zoran0104 pushed a commit to Zoran0104/spring-framework that referenced this issue Aug 20, 2021
lxbzmy pushed a commit to lxbzmy/spring-framework that referenced this issue Mar 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

4 participants