3

我試圖配置SpringSecurity與Remember Me認證一起使用。SpringSecurity RememberMeServices不是通過註釋注入

這裏是我的Java配置:

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(securedEnabled = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    UserDetailsService userDetailsService; 
    @Autowired 
    DatabasePersistentTokeRepositoryImpl databasePersistentTokeRepositoryImpl; 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder()); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception {  
     http 
     .authenticationProvider(rememberMeAuthenticationProvider()) 
     .rememberMe().tokenRepository(databasePersistentTokeRepositoryImpl).tokenValiditySeconds((int) TimeUnit.SECONDS.convert(7, TimeUnit.DAYS)) 
     .and() 
      .csrf().disable(); 
    } 

    @Bean() 
    public AuthenticationProvider rememberMeAuthenticationProvider() { 
     return new RememberMeAuthenticationProvider("KEY"); 
    } 

    @Bean() 
    public TokenBasedRememberMeServices rememberMeServices() { 
     TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices("KEY", userDetailsService); 
     rememberMeServices.setAlwaysRemember(true); 
     return rememberMeServices; 
    } 
} 

我看到RememberMeServices的不RememberMeConfigurer注射。這導致創建了引用錯誤的rememberMeServices的RememberMeAuthenticationFilter。

Spring Security文檔中有一節介紹了使用XML的此過程。 http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#session-mgmt

我的注入有什麼問題,是否有可能做到這一點,而沒有XML呢?

回答

3

你不注射它。 RememberMeConfigurer沒有自動裝配。另外你爲什麼配置這麼多的豆子?

RememberMeAuthenticationProvider已經爲您創建,如果您想使用不同的鍵使用key("KEY")指定它。這反過來將用於創建RememberMeServices

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(securedEnabled = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    UserDetailsService userDetailsService; 
    @Autowired 
    DatabasePersistentTokeRepositoryImpl databasePersistentTokeRepositoryImpl; 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder()); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception {  
     http 
     .rememberMe() 
      .key("KEY") 
      .tokenRepository(databasePersistentTokeRepositoryImpl) 
       .tokenValiditySeconds((int) TimeUnit.SECONDS.convert(7, TimeUnit.DAYS)) 
     .and() 
      .csrf().disable(); 
    } 
} 

如果你真的需要的alwaysRemember屬性設置爲true,你可以使用一個ObjectPostProcessor發佈過程中的過濾器,並從那裏配置RememberMeServices

您也可能注入了錯誤類型RememberMeServices,因爲配置的那個不使用PersistentTokeRepository

0

只需提供代碼的一個例子,一個ObjectPostProcessor,設置alwaysRemember爲true @ M-deinum的建議看起來像看起來像:

@Override 
protected void configure(HttpSecurity http) throws Exception {  
    http 
    .rememberMe() 
     .key("KEY") 
     .tokenRepository(databasePersistentTokeRepositoryImpl) 
     .tokenValiditySeconds((int) TimeUnit.SECONDS.convert(7, TimeUnit.DAYS)) 
     .withObjectPostProcessor(new ObjectPostProcessor<RememberMeAuthenticationFilter>() { 

      @Override 
      public <O extends RememberMeAuthenticationFilter> O postProcess(O object) { 

       RememberMeAuthenticationFilter rmaf = (RememberMeAuthenticationFilter) 
       PersistentTokenBasedRememberMeServices rms = (PersistentTokenBasedRememberMeServices)rmaf.getRememberMeServices(); 
       rms.setAlwaysRemember(true); 

       return object; 
      }       
     }) 
    .and() 
     .csrf().disable(); 
}