SpringSecurity RememberMeServices不是通过注释注入的

时间:2014-09-11 10:24:53

标签: java spring spring-mvc dependency-injection spring-security

我正在尝试将SpringSecurity配置为使用Remember Me身份验证。

这是我的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。这导致创建RememberMeAuthenticationFilter,它引用了错误的rememberMeServices。

Spring Security文档中有一节使用XML描述此过程。 http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#session-mgmt

我的注射有什么问题,毕竟没有XML可以做到这一点吗?

2 个答案:

答案 0 :(得分:3)

你没有注射它。 RememberMeConfigurer没有自动装配。另外你为什么要配置这么多bean?

如果您想使用其他密钥使用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

如果您确实需要将ObjectPostProcessor属性设置为true,则可以使用RememberMeServices过帐处理过滤器并从那里配置RememberMeServices

如果配置的PersistentTokeRepository没有使用{{1}},您也会注入错误的{{1}}类型。

答案 1 :(得分:0)

只是提供一个代码的示例,@ m-deinum建议将{Always}成为true的ObjectPostProcessor看起来像:

@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();
}