Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to autowire the service inside my authentication filter in Spring

I am trying to authenticate user by token, But when i try to auto wire one my services inside the AuthenticationTokenProcessingFilter i get null pointer exception. because autowired service is null , how can i fix this issue ?

My AuthenticationTokenProcessingFilter class

@ComponentScan(basePackages = {"com.marketplace"}) public class AuthenticationTokenProcessingFilter extends GenericFilterBean {      @Autowired     @Qualifier("myServices")     private MyServices service;      public void doFilter(ServletRequest request, ServletResponse response,             FilterChain chain) throws IOException, ServletException {         @SuppressWarnings("unchecked")         Map<String, String[]> parms = request.getParameterMap();          if (parms.containsKey("token")) {             try {                 String strToken = parms.get("token")[0]; // grab the first "token" parameter                  User user = service.getUserByToken(strToken);                 System.out.println("Token: " + strToken);                  DateTime dt = new DateTime();                 DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");                 DateTime createdDate = fmt.parseDateTime(strToken);                 Minutes mins = Minutes.minutesBetween(createdDate, dt);                   if (user != null && mins.getMinutes() <= 30) {                     System.out.println("valid token found");                      List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();                     authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));                      UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getEmailId(), user.getPassword());                     token.setDetails(new WebAuthenticationDetails((HttpServletRequest) request));                     Authentication authentication = new UsernamePasswordAuthenticationToken(user.getEmailId(), user.getPassword(), authorities); //this.authenticationProvider.authenticate(token);                      SecurityContextHolder.getContext().setAuthentication(authentication);                 }else{                     System.out.println("invalid token");                 }             } catch(Exception e) {                 e.printStackTrace();             }         } else {             System.out.println("no token found");         }         // continue thru the filter chain         chain.doFilter(request, response);     } } 

I Tried adding follwing in my AppConfig

@Bean(name="myServices")     public MyServices stockService() {         return new MyServiceImpl();     } 

My AppConfig Annotations are

@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.marketplace") public class AppConfig extends WebMvcConfigurerAdapter { 
like image 949
Raghu Chandra Avatar asked Sep 10 '15 06:09

Raghu Chandra


People also ask

Why Autowired is not working?

When @Autowired doesn't work. There are several reasons @Autowired might not work. When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection.

How do I turn on Autowire in Spring?

In Spring, you can use @Autowired annotation to auto-wire bean on the setter method, constructor , or a field . Moreover, it can autowire the property in a particular bean. We must first enable the annotation using below configuration in the configuration file. We have enabled annotation injection.

Can we Autowire inside a method?

@Autowired on Setter MethodsYou can use @Autowired annotation on setter methods to get rid of the <property> element in XML configuration file. When Spring finds an @Autowired annotation used with setter methods, it tries to perform byType autowiring on the method.

What is difference between @autowired and @resource in Spring?

The main difference is is that @Autowired is a spring annotation whereas @Resource is specified by the JSR-250. So the latter is part of normal java where as @Autowired is only available by spring.


2 Answers

You cannot use dependency injection from a filter out of the box. Although you are using GenericFilterBean your Servlet Filter is not managed by spring. As noted by the javadocs

This generic filter base class has no dependency on the Spring org.springframework.context.ApplicationContext concept. Filters usually don't load their own context but rather access service beans from the Spring root application context, accessible via the filter's ServletContext (see org.springframework.web.context.support.WebApplicationContextUtils).

In plain English we cannot expect spring to inject the service, but we can lazy set it on the first call. E.g.

public class AuthenticationTokenProcessingFilter extends GenericFilterBean {     private MyServices service;     @Override     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {         if(service==null){             ServletContext servletContext = request.getServletContext();             WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);             service = webApplicationContext.getBean(MyServices.class);         }         your code ...         }  } 
like image 122
Haim Raman Avatar answered Sep 28 '22 07:09

Haim Raman


I just made it work by adding

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

I am unsure why we should do this even when i tried adding explicit qualifier. and now the code looks like

public void doFilter(ServletRequest request, ServletResponse response,             FilterChain chain) throws IOException, ServletException {          SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);          @SuppressWarnings("unchecked")         Map<String, String[]> parms = request.getParameterMap();          if (parms.containsKey("token")) { 
like image 41
Raghu Chandra Avatar answered Sep 28 '22 08:09

Raghu Chandra