2017-11-01 60 views
13

मेरे पास वसंत-सुरक्षा का उपयोग कर वसंत-बूट एप्लिकेशन है। सुरक्षा कॉन्फ़िगरेशन को WebSecurityConfigurerAdapter के कई उदाहरणों में विभाजित किया गया है।वसंत सुरक्षा - एकाधिक विन्यास - लॉगआउट हैंडलर

मैं एक है जहाँ मैं सामान्य रूप में लॉगआउट कॉन्फ़िगर है:

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

और एक और WebSecurityConfigurerAdapter, जहां मैं लगभग कुछ भी नहीं करना चाहते हैं एक और 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!"); 
      }); 
} 

दोनों configure() तरीकों कहा जाता है। हालांकि, अगर मैं लॉग आउट करता हूं, तो केवल पहले LogoutHandler को कॉल किया जाता है। दोनों विन्यासों के @Order को बदलना परिणाम नहीं बदलता है।

मेरी कॉन्फ़िगरेशन में क्या गुम है?

+1

क्या आप एक ही यूआरएल में दो लॉगआउट हैंडलर पंजीकृत करने की कोशिश कर रहे हैं या आप विशेष रूप से लॉगआउट करने की कोशिश कर रहे हैं जो बाकी सब कुछ नहीं चलाता है? – Deadron

+0

लॉगआउट हैंडलर दोनों को एक ही लॉगआउट पर चलना चाहिए। –

+0

उस लिंक को आज़माएं, https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#multiple-httpsecurity मुझे लगता है कि आपका यूआरएल समान है। –

उत्तर

0

आपको अपने एकल /logout ऑपरेशन एंडपॉइंट पर CompositeLogoutHandler के साथ इस समस्या को हल करना चाहिए।

आप अभी भी वांछित रख सकते दो WebSecurityConfigurerAdapter की है, लेकिन आप एक ही समग्र कार्रवाई में दो LogoutHandler रों के लिए लॉगआउट कार्यक्षमता conglomerating कर दिया जाएगा:

new CompositeLogoutHandler(loggedOutHandler1, loggedOutHandler2); 
+0

यह मैनुअल तारों की तरह है जो मैं टालना चाहूंगा ('कंपोजिट लॉगआउट हैंडलर' के अंदर बहुत अधिक जादू नहीं हो रहा है)। मैं एक स्वतंत्र 'WebSecurityConfigurerAdapter' प्रदान करना चाहता हूं, जो स्वयं ही कार्यशीलता को जोड़ देगा। सरल उदाहरण प्रत्येक लॉगिन और लॉगआउट लॉगिंग होगा। लेकिन ऐसा लगता है कि 'addLogoutHandler'' setLogoutHandler' की तरह व्यवहार कर रहा है। –

7

जब आप कई सुरक्षा विन्यास बनाने स्प्रिंग बूट उनमें से प्रत्येक के लिए एक अलग SecurityFilterChain पैदा करेगा। WebSecurity देखें:

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

आवेदन लॉगआउट हो जाता है जब अनुरोध FilterChainProxy केवल एक 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; 
} 

तुम सच में मॉड्यूलर सुरक्षा विन्यास की जरूरत है मैं लॉगआउट और अन्य स्थानों के लिए एक अलग सुरक्षा विन्यास बनाने के लिए सुझाव है कि । आप सेम अलग विन्यास कक्षाओं में (@Bean एनोटेशन का प्रयोग करके) के रूप में लॉगआउट संचालकों को परिभाषित करने और लॉगआउट विन्यास में इन संचालकों को इकट्ठा कर सकते हैं:

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

जब मेरे पास एक ही स्थान पर सभी 'लॉगआउट हैंडलर' हैं, तो मुझे अभी भी 'कंपोजिट लॉगआउट हैंडलर' की आवश्यकता है या क्या मैं उन्हें सभी को लूप में नहीं जोड़ सकता? इसके अलावा, आपका उत्तर बहुत ही आशाजनक दिखता है। –

+1

आप लूप का उपयोग कर सकते हैं लेकिन यह बदसूरत और कम पठनीय दिखाई देगा। –

संबंधित मुद्दे