flow icon indicating copy to clipboard operation
flow copied to clipboard

NPE from WebIconsRequestMatcher

Open Artur- opened this issue 1 year ago • 3 comments
trafficstars

Description of the bug

This happens if you reload / at a suitable point during startup of an application. Once the app has fully started, this no longer reproduces.

java.lang.NullPointerException: Cannot invoke "com.vaadin.flow.server.VaadinService.getContext()" because "service" is null
	com.vaadin.flow.spring.security.WebIconsRequestMatcher.initMatchers(WebIconsRequestMatcher.java:78)
	com.vaadin.flow.spring.security.WebIconsRequestMatcher.<init>(WebIconsRequestMatcher.java:66)
	com.vaadin.flow.spring.security.RequestUtil.isCustomWebIcon(RequestUtil.java:143)
	org.springframework.security.web.util.matcher.RequestMatcher.matcher(RequestMatcher.java:48)
	org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.check(RequestMatcherDelegatingAuthorizationManager.java:79)
	org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.check(RequestMatcherDelegatingAuthorizationManager.java:48)
	org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:95)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126)
	org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:227)
	org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107)
	org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:117)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
	org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)

Expected behavior

No exception

Minimal reproducible example

A new starter with authentication

Versions

  • Vaadin / Flow version: 24.4.alpha 2
  • Java version:
  • OS version:
  • Browser version (if applicable):
  • Application Server (if applicable):
  • IDE (if applicable):

Artur- avatar Mar 14 '24 11:03 Artur-

The problem here is that during a reload, there are requests incoming before VaadinService completes its intialization.

Dispatching requests to a servlet before HttpServlet.init() is invoked seems a bit weird to me :thinking:

mcollovati avatar Mar 14 '24 12:03 mcollovati

Sounds like some other issue we had before? Icons, pwa, something ?

Artur- avatar Mar 14 '24 13:03 Artur-

A simple "fix" is to initialize WebIconsRequestMatcher in RequestUtil.isCustomWebIcon() only if VaadinService is available. The drawback is that until we get VaadinService, the requests for PWA icons will not be considered public, and the response will be HTTP 401.

mcollovati avatar Mar 14 '24 14:03 mcollovati

If we need a service instance to determine that a request is for a PWA icon, what other options are there than returning 401 if the request comes in before the service instance is available?

Artur- avatar Apr 04 '24 07:04 Artur-

I have no quick alternatives in mind right now.

Maybe generating the icons at frontend build time and storing the paths somewhere so that the registry could read the list without waiting for VaadinService could help. It could be that we already have a ticket for this

But since the issue impacts only dev-mode during hot reload, I think that for the moment we can just add the null check when instantiating WebIconsRequestMatcher.

mcollovati avatar Apr 04 '24 07:04 mcollovati

This ticket/PR has been released with Vaadin 24.4.0.alpha21 and is also targeting the upcoming stable 24.4.0 version.

vaadin-bot avatar Apr 10 '24 09:04 vaadin-bot

This ticket/PR has been released with Vaadin 24.3.10.

vaadin-bot avatar Apr 23 '24 13:04 vaadin-bot