在过滤器

时间:2016-06-08 08:19:28

标签: java spring spring-mvc

我目前正在开发一个Spring项目,我正在创建一个新的过滤器,用于检查请求中是否发送了有效的JWT。

我遇到了一个问题,我无法使用@Value注释从我的application.yml文件中获取值。

@Component
@Order(2)
public class JwtConfiguration implements Filter {

    @Value("${jwt.secret}")
    private String jwtSecret;

我知道这很好,因为我的单元测试中有相同的东西。

我已经读过某个地方,过滤器不在应用程序上下文中,因此它无法访问配置,我将无法自动连接依赖项。

有没有人知道从我的application.yml获取值到我的过滤器的好方法?

我也没有使用任何XML配置,并且更喜欢不使用它们的解决方案。

我正在使用Spring Boot 1.3.3版。

3 个答案:

答案 0 :(得分:3)

这可以通过实现ServletContextInitializer来实现。见下面的示例代码。

@Configuration
public class WebConfigurer implements ServletContextInitializer {

    @Value("${jwt.secret}")
    private String jwtSecret;

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
        initFilter(servletContext, disps);
    }


    private void initFilter(ServletContext servletContext,
                                              EnumSet<DispatcherType> disps) {
        FilterRegistration.Dynamic myFilter =
            servletContext.addFilter("myFilter",
                new MyFilterClass(jwtSecret));

        // You can pass null as first parameter to below API calls
        myFilter.addMappingForUrlPatterns(disps, true, "/content/*");
        myFilter.addMappingForUrlPatterns(disps, true, "/app/*");
        myFilter.setAsyncSupported(true);
    }

}

编辑/更新:

我想还有另一种使用Java Config添加过滤器的方法

您可以使用FilterRegistrationBean注册过滤器。您可以在此处使用setOrder方法设置顺序。但是认为它会创建尽可能多的ServletContextInitializer,因为FilterRegistrationBean是一个ServletContextInitializer See

答案 1 :(得分:1)

org.springframework.web.filter.DelegatingFilterProxy

答案 2 :(得分:0)

我将使用DelegatingFilterProxy描述在Spring启动时执行此操作的方法:

1)添加到你的application.java这个bean:

@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;
}

2)创建你的filterbean:

@Component(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public class TokenFilter extends GenericFilterBean {
@Value("${path.to.client.id}") String clientId;

@Autowired
RequestDumperFilter requestDumperFilter;

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {

    // do stuff.
}}

基本上就是这样。现在,您可以使用自己喜欢的资源保护方式。例如,我在应用程序类中添加了@EnableGlobalMethodSecurity(prePostEnabled = true)注释,并使用@PreAuthorize("hasRole('ROLE_USER')")之类的内容保护了资源。