当前位置: 动力学知识库 > 问答 > 编程问答 >

java - SpringSecurity RememberMeServices is not injected via annotations

问题描述:

I am trying to configure SpringSecurity to work with Remember Me authentication.

Here is my Java configuration:

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

}

}

I see that rememberMeServices is not injected in RememberMeConfigurer. And that results in creating RememberMeAuthenticationFilter which refers to wrong rememberMeServices.

There is a section in Spring Security documentation describing this process using XML.

http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#session-mgmt

What is wrong with my injection and is it possible do to this without XML after all?

网友答案:

You aren't injecting it. There is no autowiring for the RememberMeConfigurer. Also why are you configuring so many beans?

The RememberMeAuthenticationProvider is already created for you, if you want to use a different key specify it using key("KEY"). This in turn will be used to create the 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();
    }
}

If you really need to set the alwaysRemember property to true you could use an ObjectPostProcessor to post process the filter and configure the RememberMeServices from there.

You would also have injected the wrong type of RememberMeServices as the one configured doesn't use the PersistentTokeRepository.

网友答案:

Just to provide an example of the code that @m-deinum's suggestion of an ObjectPostProcessor that sets alwaysRemember to true would look like would look like:

@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();
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: