2015-05-15 20 views
17

Tôi có một ứng dụng Khởi động Spring sử dụng Spring-Security. Tôi có một yêu cầu phạm vi đậu mà tôi muốn autowire vào một trong các bộ lọc tùy chỉnh của tôi trong chuỗi bộ lọc bảo mật, nhưng tại thời điểm nó không hoạt động.Định cấu hình RequestContextListener trong SpringBoot

Tôi hiểu rằng một số cấu hình là cần thiết để sử dụng yêu cầu scoped đậu bên ngoài của DispatcherServlet, và đã đọc http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other này Nhưng đã không có bất kỳ thành công nào:

Đối với Servlet 3.0+, điều này có thể thực hiện theo chương trình qua giao diện WebApplicationInitializer.

(Tôi đang sử dụng mới nhất Tomcat như vậy là servlet 3+)

Tôi đã cố gắng sử dụng cả RequestContextListener và RequestContextFilter (tài liệu nói rằng họ, và DispatcherServlet, làm chính xác những điều tương tự), nhưng trong cả hai trường hợp tôi vẫn nhận sai lầm vì đối tượng autowired của tôi là null:

nỗ lực của tôi để đăng ký Lọc

@Configuration 
@ComponentScan 
@EnableAutoConfiguration 
class Application extends SpringBootServletInitializer { 

    @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     application.sources(Application) 
    } 

    @Override public void onStartup(ServletContext servletContext) throws ServletException { 
     super.onStartup(servletContext) 
     servletContext.addFilter("requestContextFilter", new RequestContextFilter()).addMappingForUrlPatterns(null, false, "/*") 
    } 

nỗ lực của tôi để đăng ký Listener

@Configuration 
@ComponentScan 
@EnableAutoConfiguration 
class Application extends SpringBootServletInitializer { 

    @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     application.sources(Application) 
    } 

    @Override public void onStartup(ServletContext servletContext) throws ServletException { 
     super.onStartup(servletContext) 
     servletContext.addListener(new RequestContextListener()) 
    } 

Tôi có thiếu thứ gì đó hiển nhiên không? Tôi đã có một cái nhìn tại mã nguồn tự động cấu hình cho Spring Boot và đã không đi qua bất cứ điều gì được nêu ra.


CẬP NHẬT

tôi đang bị một thằng ngốc, tôi đã thêm Bộ lọc của tôi trong cấu hình SpringSecurity của tôi, bên trong configure() phương pháp:

http.addFilterBefore(new PreAuthFilter(), BasicAuthenticationFilter) 

nhưng đã không đăng ký Filter mới như một Bean. Theo bình luận của M. Denium dưới đây, tôi không cần tất cả các cấu hình bổ sung đó một cách rõ ràng thêm bộ lọc/bộ lọc, chỉ cần đăng ký đậu là đủ.

+1

Bạn đang biến nó thành phức tạp. Chỉ cần thêm phương thức '@ Bean' để xây dựng' RequestContextListener'. Spring Boot sẽ làm phần còn lại. Tuy nhiên điều đó không cần thiết vì chuỗi bộ lọc bảo mật mùa xuân nằm dưới sự kiểm soát của Spring, vì vậy trừ khi bạn đang làm những thứ bên ngoài chuỗi bộ lọc thực tế, bạn sẽ cần phải đăng ký cái này nó chỉ hoạt động. –

+0

Cảm ơn @ M.Deinum - hóa ra tôi đã là một thằng ngốc - tôi đã cập nhật câu hỏi với các chi tiết, nhưng về cơ bản đã không đăng ký bộ lọc chính xác. – rhinds

Trả lời

31

Như được nêu chi tiết trong phần cập nhật/nhận xét, điều này là do sự ngu ngốc của chính tôi.

mùa xuân-Boot có thể autowire Yêu cầu/phiên scoped đậu vào bộ lọc của nằm ngoài của DispatcherServlet Theo tài liệu của Spring, chúng ta cần phải thêm RequestContextListener hoặc RequestContextFilter để kích hoạt chức năng này:

Để hỗ trợ phạm vi đậu ở mức yêu cầu, phiên và mức độ phiên họp toàn cầu (hạt cà phê có phạm vi web), một số cấu hình ban đầu nhỏ là bắt buộc trước khi bạn xác định hạt của mình. (Thiết lập ban đầu Đây không phải là cần thiết cho các phạm vi tiêu chuẩn, singleton và nguyên mẫu.) ...

Nếu bạn truy cập scoped đậu trong Spring Web MVC, có hiệu lực trong thời hạn yêu cầu được xử lý bởi các DispatcherServlet xuân hoặc DispatcherPortlet, sau đó không cần thiết lập đặc biệt: DispatcherServlet và DispatcherPortlet đã phơi bày tất cả trạng thái có liên quan .

Để xử lý điều này, tôi cần phải đăng ký một bean RequestContextListener:

@Bean public RequestContextListener requestContextListener(){ 
    return new RequestContextListener(); 
} 

Nếu bạn không đăng ký đậu đó, bạn sẽ nhận được một lỗi nói rằng bạn đang cố gắng truy cập vào các phạm vi yêu cầu bên ngoài của DispatcherServlet.

Vấn đề tôi có kinh nghiệm (đối tượng autowired chỉ không được tiêm) được gây ra bởi thực tế là tôi chỉ đăng ký bộ lọc tùy chỉnh của tôi như một cá thể của lớp tiêu chuẩn, không phải là một mùa xuân quản lý đậu:

http.addFilterBefore(new PreAuthFilter(), BasicAuthenticationFilter) 

Để giải quyết điều này, tôi chỉ di chuyển việc tạo ra các PreAuthFilter đến một phương phápsepearte, chức năng @Autowired sau đó làm việc tốt.

+2

cảm ơn bạn và đừng quá cố gắng. ngu dốt. Câu hỏi và câu trả lời của bạn thực sự đã giúp tôi. – arcseldon

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