2014-09-11 143 views
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(); 
}