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

DelegatingFilterProxy not found WebApplicationContext when start context with AbstractAnnotationConfigDispatcherHandlerInitializer [SPR-16096] #20645

Closed
spring-issuemaster opened this issue Oct 22, 2017 · 4 comments
Assignees

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Oct 22, 2017

José María Sola Durán opened SPR-16096 and commented

I start a new project with Spring WebFlux. I want integrate this project with the new version of Spring Security 5.0.0.M5. I start the WebFlux context with WebAppInitializer, in particular extends the abstract class AbstractAnnotationConfigDispatcherHandlerInitializer. The code is below

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherHandlerInitializer {
	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		super.onStartup(servletContext);
		
		/* Spring Security Filter */
		FilterRegistration.Dynamic securityFilterRegistration = servletContext.addFilter(DelegatingFilterProxy.class.getSimpleName(), DelegatingFilterProxy.class);
		securityFilterRegistration.setAsyncSupported(true);
		securityFilterRegistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC), false, "/*");
	}
	
	@Override
	protected String getServletMapping() {
		return "/api/*";
	}

	@Override
	protected Class<?>[] getConfigClasses() {
		return Stream.of(AppConfig.class, SpringWebFluxConfig.class).toArray(size -> new Class<?>[size]);
	}
}

But when I send a request for de API, I obtaing the next exception:

java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener or DispatcherServlet registered?
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:789)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1437)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

AbstractAnnotationConfigDispatcherHandlerInitializer instance a HttpHandler for Non I/O Blocking request, but ¿why DelegatingProxy not found WebApplicationContext if it's started?

I attach the complete log of Tomcat 8.5.x server.


Affects: 5.0 GA

Attachments:

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Oct 22, 2017

José María Sola Durán commented

It's works if copy partial code of AbstractSecurityWebApplicationInitializer#onStartup() method, in my WebAppInitializer. The code is the next:

@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		/* Start root context Spring and Security context */
		AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
		rootAppContext.register(AppConfig.class);
		servletContext.addListener(new ContextLoaderListener(rootAppContext));
		servletContext.addListener(HttpSessionEventPublisher.class);
		servletContext.addListener(RequestContextListener.class);

		servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
		String filterName = "springSecurityFilterChain";
		DelegatingFilterProxy springSecurityFilterChain = new DelegatingFilterProxy(filterName);
		Dynamic registration = servletContext.addFilter(filterName, springSecurityFilterChain);
		if (registration == null) {
			throw new IllegalStateException("Duplicate Filter registration for '" + filterName
					+ "'. Check to ensure the Filter is only configured once.");
		}
		registration.setAsyncSupported(true);
		EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR,
				DispatcherType.ASYNC);
		registration.addMappingForUrlPatterns(dispatcherTypes, false, "/*");

		super.onStartup(servletContext);
	}

I need explicitly start ContextLoaderListener, in order to the DelegatingFilterProxy finds WebApplicationContext. ¿It's correct? I think that I shouldn't start ContextLoaderListener manually.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Oct 23, 2017

Rossen Stoyanchev commented

WebFlux uses the Servlet API only as a low level adapter layer. It does not expose the Servlet API in any way because it is synchronous (e.g. javax.servlet.Filter return void) and also because it cannot be used as a common abstraction over servers with native APIs (e.g. Netty, Undertow). WebFlux provides its own WebFilter which has a non-blocking contract and consequently Spring Security uses Spring Web reactive APIs to integrate with WebFlux. So you're going down the wrong path there trying to bring in a DelegatingFilterProxy.

Spring Security provides @EnableWebFluxSecurity based configuration. See the sample and also some comments from the M4 blog post.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Oct 23, 2017

Rossen Stoyanchev commented

Resolving but feel free to comment.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Oct 23, 2017

José María Sola Durán commented

Thanks for the quick answer.

I will try it with this solution and I will tell you my feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.