Egor
Egor

Reputation: 309

NullPointerException. Spring security filter failed

I have no ideas why this app does not start displaying this error. I tried to use Spring Security and JWT.

2020-Feb-17 12:29:07 PM [main] INFO  org.springframework.aop.framework.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.web.filter.OncePerRequestFilter.doFilter(javax.servlet.ServletRequest,javax.servlet.ServletResponse,javax.servlet.FilterChain) throws javax.servlet.ServletException,java.io.IOException] because it is marked as final: Consider using interface-based JDK proxies instead!
2020-Feb-17 12:29:07 PM [main] INFO  org.springframework.aop.framework.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.web.filter.GenericFilterBean.init(javax.servlet.FilterConfig) throws javax.servlet.ServletException] because it is marked as final: Consider using interface-based JDK proxies instead!
2020-Feb-17 12:29:07 PM [main] ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Exception starting filter [jwtRequestFilter]
java.lang.NullPointerException: null
    at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:241) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:270) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:106) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4533) [tomcat-embed-core-9.0.29.jar:9.0.29]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5172) [tomcat-embed-core-9.0.29.jar:9.0.29]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [tomcat-embed-core-9.0.29.jar:9.0.29]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) [tomcat-embed-core-9.0.29.jar:9.0.29]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) [tomcat-embed-core-9.0.29.jar:9.0.29]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) [tomcat-embed-core-9.0.29.jar:9.0.29]
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) [?:?]
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) [tomcat-embed-core-9.0.29.jar:9.0.29]
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:841) [tomcat-embed-core-9.0.29.jar:9.0.29]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [tomcat-embed-core-9.0.29.jar:9.0.29]

This is filter code. I don't understand what is wrong with it. The application just crushed upon loading time with null pointer exception related to the security filter.

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {

        final String requestTokenHeader = request.getHeader("Authorization");
        String email = null;
        String jwtToken = null;

        if (requestTokenHeader != null && requestTokenHeader.startsWith("FC ")) {
            jwtToken = requestTokenHeader.replace("FC ", "");
            try {
                email = jwtTokenUtil.getEmailFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                System.out.println("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                System.out.println("JWT Token has expired");
            }
        } else {
            logger.warn("JWT Token does not begin with FC String");
        }

        if (email != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(email);
            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken
                        .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        chain.doFilter(request, response);
    }

@UPDATE

added method where I add filter.

@Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable()
                .authorizeRequests().antMatchers("/service/**").permitAll()
                .anyRequest().authenticated().and()
                .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

Upvotes: 4

Views: 5384

Answers (5)

Abhinandan Sanduja
Abhinandan Sanduja

Reputation: 21

I might be bit late here, but i also faced this issue and was able to debug the actual reason as to why it happens. Spring AOP creates proxies by extension and we have a init() defined in GenericFilterBean

public final void init(FilterConfig filterConfig) throws ServletException {
...
}

Since the init method is defined as final and final methods and classes can't be extended which is the necessity for creating proxies. Hence SpringAOP is not able to create a proper proxy for this method and delegation of method call from proxy object to target object fails and it returns null value from proxy object.

In short, All the classes or methods which are defined as final in java will have issues when you are using SpringAOP.

So, the solution like other users have mentioned is to exclude the GenericFilterBean using AOP pointcuts.

Upvotes: 0

Dmitry Murashov
Dmitry Murashov

Reputation: 1

I had this because didn't registered Filter with FilterRegistrationBean. After this error disappeared. https://www.techiedelight.com/how-to-define-custom-filters-spring-boot-application/ second case

Upvotes: 0

Ahmad Zahabi
Ahmad Zahabi

Reputation: 1268

I faced the same issue and I resolved it in this way:

1- create a custom annotation:

@Target(ElementType.METHOD)
public @interface NoLogging
{
}

2- annotate the doFilterInternal

    @Override
    @NoLogging
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)

3- exclude the methods annotated with this annotation from AOP:

@Before(value = "execution(* com.company..*..*(..)) && !@annotation(com.company.aop.NoLogging)")
    public void logEntry(JoinPoint joinPoint)

Upvotes: 3

Shaikh Dahood
Shaikh Dahood

Reputation: 41

I was facing exactly the same issue and it was the spring aop configuration that I had in my app. I added a pointcut to exclude GenricFilterBean class implementation and everything seems to work fine.

Upvotes: 4

James Williams
James Williams

Reputation: 71

A little late to the game here but i just had this same exception. The clue is the CGLIB proxies in the INFO above the null pointer and the Generic Filter exception. Do you have @Transactional anywhere in here? Have you defined any transactional functionality around these methods? I had @Transactional on my doFilterInternal. Removing the @Transactional fixed my issue.

Upvotes: 1

Related Questions