2014-06-23 19 views
5

Tôi đang sử dụng Spring-Security 3.2.4 và Spring Boot 1.1.0 (và các phiên bản phụ thuộc có liên quan 4.X). Tôi đang viết một ứng dụng web sẽ chạy trong một tomcat được nhúng.Thêm bộ lọc tùy chỉnh được gọi sau bộ lọc bảo mật mùa xuân trong môi trường Servlet 3+

Tôi đang cố gắng thêm hai bộ lọc bổ sung (không liên quan đến bảo mật mùa xuân) mà một trong số chúng sẽ được gọi trước Spring-Security-FilterChainProxy và một bộ lọc khác sẽ được gọi sau Spring-Security-FilterChainProxy.

My Xuân-An ninh các file cấu hình:

@Configuration 
@EnableWebMvcSecurity 
public class SecurityCtxConfig extends WebSecurityConfigurerAdapter { 

@Autowired 
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
    auth 
    .inMemoryAuthentication() 
     .withUser("user").password("pass").roles("USER"); 
} 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http.csrf() 
      .disable() 
      .authorizeRequests() 
      .anyRequest() 
      .authenticated() 
      .and() 
      .formLogin() 
      .usernameParameter("user").passwordParameter("password"); 
} 
} 

Và lớp Main (Application.class):

@Configuration 
@ComponentScan 
@EnableAutoConfiguration 
public class Application { 

    @Bean 
RequestFilter beforeSpringSecurityFilter(){ 
    return new RequestFilter(); 
} 

@Bean 
RequestFilter afterSpringSecurityFilter(){ 
    return new RequestFilter(); 
} 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

Và việc thực hiện lọc:

public class RequestFilter extends OncePerRequestFilter { 

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

} 

Có cách kiểm soát thứ tự gọi khi tính đến FilterChainProxy (đó là tạo ra bởi con ong WebSecurityConfigurerAdapter? Được percise, thứ tự yêu cầu là:

  1. request-lọc-1
  2. mùa xuân-An ninh FilterChain
  3. request-lọc-2

Cảm ơn

Trả lời

5

Các FilterChainProxy sử dụng bởi Spring Security không phải là Ordered (nếu đó là bạn có thể đặt hàng tất cả các bộ lọc của bạn). Nhưng bạn sẽ có thể đăng ký nó trong một FilterRegistrationBeanOrdered và đăng ký các bộ lọc khác của bạn theo cùng một cách. Trong trường hợp của bộ lọc bảo mật, bạn có thể tiêm nó bằng tên vào bean đăng ký. Những người khác bạn có thể có thể tiêm bằng cách gọi một phương thức @Bean.

+0

Cảm ơn bạn rất nhiều @Dave Syer. Những gì tôi vẫn còn thiếu là tại sao không có hai chuỗi bộ lọc bây giờ, tôi có nghĩa là làm thế nào là khuôn khổ là một ware để thực tế là tôi đã thêm một FilterRegistration Bean (kết thúc tốt đẹp chuỗi bộ lọc) để các chuỗi bộ lọc nó tự wont được thêm vào như một bộ lọc, tôi sẽ hạnh phúc hơn tôi, bạn có thể xây dựng một chút. – Modi

+0

Xem mã trong 'EmbeddedWebApplicationContext', trong đó nó phân tích' FilterRegistrationBeans'. Chúng tôi không tăng gấp đôi đăng ký các bộ lọc đã là một phần của một đăng ký. –

+0

OK, cảm ơn rất nhiều. – Modi

3

Đồng ý với mọi thứ được Dave Syer nêu;) nhưng muốn thêm ví dụ Java Config bằng cách sử dụng FilterRegistrationBean.

Trong trường hợp của mình, tôi nhận thấy rằng bộ lọc bảo mật tùy chỉnh của tôi (sử dụng Spring Security) đã được kích hoạt hai lần cho mọi yêu cầu. Thêm cấu hình FilterRegistrationBean đã sửa lỗi này.

@Bean(name = "myFilter") 
    public MyAuthenticationFilter myAuthenticationFilter(final MyAuthenticationEntryPoint entryPoint) { 
     final MyAuthenticationFilter filter = new MyAuthenticationFilter(); 
     filter.setEntryPoint(entryPoint); 
     return filter; 
    } 

    /** 
    * We do this to ensure our Filter is only loaded once into Application Context 
    * 
    */ 
    @Bean(name = "authenticationFilterRegistration") 
    public FilterRegistrationBean myAuthenticationFilterRegistration(final MyAuthenticationFilter filter) { 
     final FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); 
     filterRegistrationBean.setFilter(filter); 
     filterRegistrationBean.setEnabled(false); 
     return filterRegistrationBean; 
    } 

(Về vấn đề cụ thể của tôi về bộ lọc được đăng ký hai lần trong Application Context - Thay vì sử dụng một FilterRegistrationBean, tôi cũng phát hiện được triển khai lại các MyAuthenticationFilter kế thừa từ OncePerRequestFilter thay vì GenericFilterBean cũng làm việc Tuy nhiên, OncePerRequestFilter hỗ trợ là. từ Servlet 3.x trở lên và vì tôi đang viết thư viện công cộng, có thể cần hỗ trợ từ Servlet 2.x)

Các vấn đề liên quan