0

my custom filter is not taking value from .properties/.yml file Note: property file is located at src/main/resources folder

@Slf4j
public class CustomFilter implements Filter {

    @Value("${xyz.domainName:http://localhost:8080/x1}")
    private String DOMAIN_NAME;

    private static final String REDIRECT_URL_ENDPOINT = "/v1/xyz/abc/";

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String url = request.getRequestURL().toString();
        String id = url.substring(url.lastIndexOf("/") + 1);

        if (url.startsWith(DOMAIN_NAME)) {
            ServletContext context = request.getServletContext();
            RequestDispatcher dispatcher = context.getRequestDispatcher(REDIRECT_URL_ENDPOINT + id);
            dispatcher.forward(request, response);
        }
        else
            filterChain.doFilter(request, response);
    }

}

Edit (Added WebSecurityConfigClass): My WebSecurityConfig class looks like:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(new CustomFilter(), ApiKeyAuthFilter.class);

    }
}
  • Don't you have any application.properties or application.yml file? If yes post you yml file aslo – Avijit Barua Mar 08 '22 at 06:47
  • it should take at least default value no? xyz: domainName: "http://localhost:8080/x1/" this is added in yml file – Null Pointer Mar 08 '22 at 07:05
  • I think the way you assigned @Value in not appropiate. That's why I am asking you to post your application.yml file – Avijit Barua Mar 08 '22 at 07:25
  • It was not an issue related to the .yml/.properties file, @Alex's suggested solution worked perfectly with a little modification mentioned in the below solution comment thread. – Null Pointer Mar 09 '22 at 06:09

1 Answers1

0

Looking at the code, you filter is not managed by the Spring Context, therefore Spring-related functionalities like @Value do not work. So, let Spring take care of your filter.

@Component
@Slf4j
public class CustomFilter implements Filter {

@Value("${xyz.domainName:http://localhost:8080/x1}")
private String DOMAIN_NAME;

private static final String REDIRECT_URL_ENDPOINT = "/v1/xyz/abc/";

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
        throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    String url = request.getRequestURL().toString();
    String id = url.substring(url.lastIndexOf("/") + 1);

    if (url.startsWith(DOMAIN_NAME)) {
        ServletContext context = request.getServletContext();
        RequestDispatcher dispatcher = context.getRequestDispatcher(REDIRECT_URL_ENDPOINT + id);
        dispatcher.forward(request, response);
    }
    else
        filterChain.doFilter(request, response);
}

@Bean
public FilterRegistrationBean registerFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(this);
    registration.addUrlPatterns("/*");
    return registration;
}

}

If you want to register the filter before a Spring security filter you can do this:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private Customfilter customfilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(customfilter, ApiKeyAuthFilter.class);

    }
}
Alex
  • 16
  • 3
  • I tried both solutions but it's not working for me. – Null Pointer Mar 08 '22 at 06:35
  • Take a look at this answer: https://stackoverflow.com/a/44114108/15203875. The two solutions from my answer did work for me in the past. – Alex Mar 08 '22 at 06:40
  • ``` @Bean public FilterRegistrationBean securityFilterChainRegistration() { DelegatingFilterProxy delegatingFilterProxy = new DelegatingFilterProxy(); delegatingFilterProxy.setTargetBeanName(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME); FilterRegistrationBean registrationBean = new FilterRegistrationBean(delegatingFilterProxy); registrationBean.setName(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME); registrationBean.addUrlPatterns("/*"); return registrationBean; } ``` I have added this in my application class. – Null Pointer Mar 08 '22 at 07:03
  • and added @Component(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME) on my filter class but still getting null for that @Value variable – Null Pointer Mar 08 '22 at 07:03
  • I updated my original answer. Please try the solution. – Alex Mar 08 '22 at 07:13
  • Thanks, Alex for your effort, but this is the exact solution I have been trying for 2 days but it is not working – Null Pointer Mar 08 '22 at 07:21
  • protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore(new ApiKeyAuthFilter(), BasicAuthenticationFilter.class); http.addFilterBefore(new CustomFilter(), ApiKeyAuthFilter.class); } Is this thing causing the issue?, because I have added my filter in this manner in WebSecurityConfig class. – Null Pointer Mar 08 '22 at 07:24
  • I think so. In your implementation http.addFilterBefore(new CustomFilter(), ApiKeyAuthFilter.class); you write new CustomFilter() which creates a new object so the @Value is not working there because the new object is not managed by Spring. – Alex Mar 08 '22 at 07:30
  • I gave you an example of using the filter with Spring security in the original post. – Alex Mar 08 '22 at 07:37
  • Thanks @Alex the edited solution worked for me after doing a little modification. 1. Instead of implementing `Filter`, I extended my class with `OncePerRequestFilter` because my CustomFilter was being called twice for a single request may be because of Autowiring it in WebSecurityConfig class. 2. I have not written the `registerBean` method for external bean registration, @Component did its job perfectly. And yes it worked as I wanted. Great Thanks again for helping me out with this headache :) – Null Pointer Mar 08 '22 at 19:24