0

I have Spring based REST API in which I am trying to add a custom filter. This filter will be used for token based verification. However, the service call gives null pointer exception. The filter is also added under web.xml for registration.

The below service call gives null pointer. Please note that I am not using Spring security for authentication.

boolean flag = authTokenService.validateRESTAccessRequest(authToken);

Rest of the code works fine. I tried editing the filter with extending OncePerRequestfilter instead of GenericFilter bean. But the same problem persists. What needs to be done?

package org.application.web.filter;

  import java.io.IOException;
  import javax.servlet.FilterChain;
  import javax.servlet.ServletException;
  import javax.servlet.ServletOutputStream;
  import javax.servlet.ServletRequest;
  import javax.servlet.ServletResponse;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;

  import org.application.services.AuthTokenService;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Component;
  import org.springframework.web.filter.GenericFilterBean;

  @Component
  public class RestApiAuthFilter extends GenericFilterBean {
    @Autowired
    AuthTokenService authTokenService;

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
            throws IOException, ServletException {

         final HttpServletRequest request = (HttpServletRequest) req;
         final HttpServletResponse response = (HttpServletResponse) res;
         final String authHeader = request.getHeader("Authorization");

        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);

            filterChain.doFilter(request, response);
        } else {

            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                ServletOutputStream os = response.getOutputStream();
                os.write("INVALID AUTHNETICATION TOKEN".getBytes());
                os.close();

                return;
            }

            final String authToken = authHeader.substring(7);
            boolean flag = authTokenService.validateRESTAccessRequest(authToken);

            if (flag == false) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                ServletOutputStream os = response.getOutputStream();
                os.write("INVALID AUTHNETICATION TOKEN".getBytes());
                os.close();

                return;
            } else {
                filterChain.doFilter(request, response);
            }
        }

    }
    }

web.xml has below entries for filter,

<filter>
        <filter-name>restApiAuthFilter</filter-name>
        <filter-class>org.application.web.filter.RestApiAuthFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>restApiAuthFilter</filter-name>
        <url-pattern>/secure/*</url-pattern>
    </filter-mapping>

The stack trace of the error is below,

java.lang.NullPointerException
    at org.application.web.filter.RestApiAuthFilter.doFilter(RestApiAuthFilter.java:46)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.application.web.filter.CORSFilter.doFilterInternal(CORSFilter.java:27)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Nikhil
  • 861
  • 11
  • 15
  • authTokenService may not be autowired. Is this class scanned by component scan? Could you add your spring configuration to your question? – Alex M981 Jan 23 '18 at 05:16
  • please add the stack trace. – Rakesh Jan 23 '18 at 05:32
  • Please check my original post. I am editing that wit stack trace. – Nikhil Jan 23 '18 at 07:01
  • What is AuthTokenService..?? Is it a third party library or your custom service for Authentication? – miiiii Jan 23 '18 at 07:09
  • AuthTokenService is my custom service written in Spring for authentication. – Nikhil Jan 23 '18 at 07:50
  • Try to check authTokenService is null or not since I don't think your authToken is null... If authTokenService is null then your wired is incorrect and we will need to see your configuration and packet hierarchy to know more. – Nguyen Pham Jan 24 '18 at 09:08

1 Answers1

0

I could resolve the issue. Below link came to rescue...

Access to spring beans from OncePerRequestFilter

I made below changes

web.xml

<filter>
    <filter-name>RestApiAuthFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
</filter>

<filter-mapping>
    <filter-name>RestApiAuthFilter</filter-name>
    <url-pattern>/secure/*</url-pattern>
</filter-mapping>

spring context xml

<bean name="RestApiAuthFilter" class="org.application.web.filter.RestApiAuthFilter">
       <property name="authTokenService" ref="authTokenService"/>
    </bean>

    <bean id="authTokenService"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="transactionManager" />
        <property name="target" ref="authTokenServiceTarget" />
        <property name="proxyInterfaces">
            <value>org.application.services.AuthTokenService</value>
        </property>
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_NOT_SUPPORTED, readOnly</prop>
            </props>
        </property>
    </bean>
    <bean id="authTokenServiceTarget"
        class="org.application.services.impl.AuthTokenServiceImpl">
    </bean>

RestApiAuthFilter.java

package org.application.web.filter;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.application.services.AuthTokenService;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

@Component
public class RestApiAuthFilter extends OncePerRequestFilter {

    AuthTokenService authTokenService;

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

        final String authHeader = request.getHeader("Authorization");

        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);

            filterChain.doFilter(request, response);
        } else {

            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                ServletOutputStream os = response.getOutputStream();
                os.write("INVALID AUTHNETICATION TOKEN".getBytes());
                os.close();

                return;
            }

            boolean flag = authTokenService.validateRESTAccessRequest(request);

            if (flag == false) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                ServletOutputStream os = response.getOutputStream();
                os.write("INVALID AUTHNETICATION TOKEN".getBytes());
                os.close();

                return;
            } else {
                filterChain.doFilter(request, response);
            }
        }
    }

    public AuthTokenService getAuthTokenService() {
        return authTokenService;
    }

    public void setAuthTokenService(AuthTokenService authTokenService) {
        this.authTokenService = authTokenService;
    }
}
Nikhil
  • 861
  • 11
  • 15