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 {
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.
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.
@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.
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.
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 ... } }
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")) {
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With