2017-11-01 81 views
13

Tôi có một ứng dụng khởi động mùa xuân bằng cách sử dụng bảo mật mùa xuân. Cấu hình bảo mật được chia thành nhiều phiên bản WebSecurityConfigurerAdapter.Bảo mật mùa xuân - nhiều cấu hình - thêm LogoutHandler

tôi có một nơi nào để cấu hình logout nói chung:

@Override 
protected void configure(HttpSecurity http) throws Exception { 

    // configure logout 
    http 
      .logout() 
      .logoutUrl("/logout") 
      .invalidateHttpSession(true) 
      .addLogoutHandler((request, response, authentication) -> { 
       System.out.println("logged out 1!"); 
      }) 
      .permitAll(); 

    // ... more security configuration, e.g. login, CSRF, rememberme 
} 

Và có một WebSecurityConfigurerAdapter, nơi tôi muốn làm gần như không có gì, ngoại trừ thêm một LogoutHandler:

@Override 
protected void configure(HttpSecurity http) throws Exception { 

    // configure logout 
    http 
      .logout() 
      .logoutUrl("/logout") 
      .addLogoutHandler((request, response, authentication) -> { 
       System.out.println("logged out 2!"); 
      }); 
} 

Cả configure() phương pháp được gọi là. Tuy nhiên, nếu tôi đăng xuất, chỉ có LogoutHandler đầu tiên được gọi. Việc thay đổi @Order của cả hai cấu hình sẽ không thay đổi kết quả.

Điều gì bị thiếu trong cấu hình của tôi?

+1

Bạn đang cố gắng đăng ký hai trình xử lý đăng xuất cho cùng một url hoặc bạn đang cố gắng đăng xuất cụ thể để không chạy mọi thứ khác? – Deadron

+0

Cả hai LogoutHandlers nên chạy trên cùng một đăng xuất. –

+0

Hãy thử liên kết đó, https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#multiple-httpsecurity Tôi nghĩ rằng url của bạn giống nhau. –

Trả lời

0

Bạn nên giải quyết vấn đề này với CompositeLogoutHandler trên điểm cuối hoạt động /logout duy nhất của mình.

Bạn vẫn có thể giữ hai WebSecurityConfigurerAdapter 's như mong muốn, nhưng bạn sẽ được gắn kết lại các chức năng logout cho hai LogoutHandler s thành một hành động hợp duy nhất:

new CompositeLogoutHandler(loggedOutHandler1, loggedOutHandler2); 
+0

Đó là loại dây dẫn sử dụng tôi muốn tránh (không có nhiều ma thuật xảy ra bên trong 'CompositeLogoutHandler'). Tôi muốn cung cấp một 'WebSecurityConfigurerAdapter' độc lập, nó sẽ bổ sung thêm chức năng làm việc của chính nó. Ví dụ đơn giản nhất sẽ đăng nhập mỗi lần đăng nhập và đăng xuất. Nhưng có vẻ như 'addLogoutHandler' hoạt động giống như' setLogoutHandler' hơn. –

7

Khi bạn tạo một vài cấu hình an ninh mùa xuân Boot sẽ tạo ra một SecurityFilterChain riêng biệt cho mỗi người trong số họ. Xem WebSecurity:

@Override 
protected Filter performBuild() throws Exception { 
    // ... 
    for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) { 
     securityFilterChains.add(securityFilterChainBuilder.build()); 
    } 
    // ... 
} 

Khi ứng dụng được đăng xuất yêu cầu FilterChainProxy sẽ trở lại chỉ có một SecurityFilterChain:

private List<Filter> getFilters(HttpServletRequest request) { 
    for (SecurityFilterChain chain : filterChains) { 
     // Only the first chain that matches logout request will be used: 
     if (chain.matches(request)) { 
      return chain.getFilters(); 
     } 
    } 

    return null; 
} 

Nếu bạn thực sự cần cấu hình bảo mật mô-đun tôi sẽ đề nghị để tạo ra một cấu hình bảo mật riêng biệt cho logout và cõi khác . Bạn có thể xác định xử lý logout như đậu (sử dụng @Bean chú thích) trong các lớp cấu hình khác nhau và thu thập những xử lý trong cấu hình logout:

WebSecurityLogoutConfiguration.java

@Configuration 
@Order(99) 
public class WebSecurityLogoutConfiguration extends WebSecurityConfigurerAdapter { 

    // ALL YOUR LOGOUT HANDLERS WILL BE IN THIS LIST 
    @Autowired 
    private List<LogoutHandler> logoutHandlers; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     // configure only logout 
     http 
       .logout() 
       .logoutUrl("/logout") 
       .invalidateHttpSession(true) 
       // USE CompositeLogoutHandler 
       .addLogoutHandler(new CompositeLogoutHandler(logoutHandlers)); 
     http.csrf().disable(); // for demo purposes 
    } 
} 

WebSecurity1Configuration.java

@Configuration 
@Order(101) 
public class WebSecurity1Configuration extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     // ... more security configuration, e.g. login, CSRF, rememberme 
     http.authorizeRequests() 
       .antMatchers("/secured/**") 
       .authenticated(); 
    } 

    // LOGOUT HANDLER 1 
    @Bean 
    public LogoutHandler logoutHandler1() { 
     return (request, response, authentication) -> { 
      System.out.println("logged out 1!"); 
     }; 
    } 
} 

WebSecurity2Configuration.java

@Configuration 
@Order(102) 
public class WebSecurity2Configuration extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests() 
       .antMatchers("/api/**") 
       .permitAll(); 
    } 

    // LOGOUT HANDLER 2 
    @Bean 
    public LogoutHandler logoutHandler2() { 
     return (request, response, authentication) -> { 
      System.out.println("logged out 2!"); 
     }; 
    } 
} 
+0

Khi tôi có tất cả 'LogoutHandler' ở một nơi duy nhất, tôi vẫn cần' CompositeLogoutHandler' hay tôi không thể thêm tất cả chúng trong một vòng lặp? Khác hơn thế, câu trả lời của bạn trông rất hứa hẹn. –

+1

Bạn có thể sử dụng vòng lặp nhưng nó sẽ trông xấu xí và ít có thể đọc được. –

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