【问题标题】:AuthenticationManager when updating to Spring-security-3.2.0.RC2更新到 Spring-security-3.2.0.RC2 时的 AuthenticationManager
【发布时间】:2013-11-16 21:50:09
【问题描述】:

我最近从 RC1 更新到 spring-security-3.2.0.RC2,根据博客文章,QUIESCENT_POST_PROCESSOR 已被删除。在我用来创建如下所示的 AuthenticationManager bean 之前:

@Bean(name = {"defaultAuthenticationManager", "authenticationManager"})
public AuthenticationManager defaultAuthenticationManager() throws Exception {
    return new AuthenticationManagerBuilder(null).userDetailsService(context.getBean(MyUserDetailsService.class)).passwordEncoder(new Md5PasswordEncoder()).and().build();
}

所以我把它改成了:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws BeansException, Exception {
    auth.userDetailsService(context.getBean(MyUserDetailsService.class)).passwordEncoder(new Md5PasswordEncoder());
}

但不幸的是,我无法再获得 AuthenticationManager。我也在像这样创建 RememberMeAuthenticationFilter:

@Bean(name = { "defaultRememberMeAuthenticationFilter", "rememberMeAuthenticationFilter" })
protected RememberMeAuthenticationFilter defaultRememberMeAuthenticationFilter() throws Exception {
    return new RememberMeAuthenticationFilter(defaultAuthenticationManager(), context.getBean(DefaultRememberMeServices.class));
}

如你所见,我需要获取 AuthenticationManager,但我不知道怎么做???

【问题讨论】:

    标签: spring-security


    【解决方案1】:

    您真的不需要持有 AuthenticationManager。从 the javadoc of HttpSecurity 开始,以下内容应该可以正常工作:

    @Configuration
    @EnableWebSecurity
    public class RememberMeSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth)
                throws Exception {
            auth
                 .inMemoryAuthentication()
                      .withUser("user").password("password").roles("USER");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .antMatchers("/**").hasRole("USER")
                    .and()
                .formLogin()
                    .permitAll()
                    .and()
                // Example Remember Me Configuration
                .rememberMe();
        }
    }
    

    当然,如果您使用全局 AuthenticationManager,这也可以:

    @Configuration
    @EnableWebSecurity
    public class RememberMeSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth)
                throws Exception {
            auth
                 .inMemoryAuthentication()
                      .withUser("user").password("password").roles("USER");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .antMatchers("/**").hasRole("USER")
                    .and()
                .formLogin()
                    .permitAll()
                    .and()
                // Example Remember Me Configuration
                .rememberMe();
        }
    }
    

    唯一的区别是第一个示例将 AuthenticationManger 隔离到 HttpSecurity,而第二个示例将允许 AuthenticationManager 被全局方法安全性或另一个 HttpSecurity (WebSecurityConfigurerAdapter) 使用。

    这样做的原因是 .rememberMe() 会自动找到 AuthenticationManager、UserDetailsS​​ervice 并在创建 RememberMeAuthenticationFilter 时使用它。它还会创建适当的 RememberMeServices,因此无需这样做。当然,如果你想自定义 .rememberMe() ,还有其他选项,请参考RememberMeConfigurer javadoc 了解更多选项。

    如果您真的需要对 AuthenticationManager 实例的引用,您可以执行以下操作:

    @Configuration
    @EnableWebSecurity
    public class RememberMeSecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private AuthenticationManagerBuilder auth;
    
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth)
                throws Exception {
            auth
                 .inMemoryAuthentication()
                      .withUser("user").password("password").roles("USER");
        }
    
        @Bean
        public AuthenticationManager authenticationManager() {
            return auth.build();
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .antMatchers("/**").hasRole("USER")
                    .and()
                .formLogin()
                    .permitAll()
                    .and()
                // Example Remember Me Configuration
                .rememberMe();
        }
    }
    

    如果您想拥有多个 AuthenticationManager 实例,您可以执行以下操作:

        @Autowired
        private ObjectPostProcessor<Object> opp;
    
        public AuthenticationManager authenticationManager()
                throws Exception {
            return new AuthenticationManagerBuilder(opp)
                .inMemoryAuthentication()
                   .withUser("user").password("password").roles("USER").and()
                .and()
                .build();
        }
    
        public AuthenticationManager authenticationManager2()
                throws Exception {
            return new AuthenticationManagerBuilder(opp)
                .inMemoryAuthentication()
                   .withUser("admin").password("password").roles("ADMIN").and()
                .and()
                .build();
        }
    

    注意这几乎和你手头的东西一样,除了使用 @Autowired 注释而不是使用 QUIESENT_POST_PROCESSOR 而是使用真正的 ObjectPostProcessor

    PS:感谢您试用 RC2!

    【讨论】:

    • 嗨,Rob,我有这个使用的服务
    • 嗨 Rob,我有这个使用 AuthenticationManager 的服务,如下所示:\@Resource private AuthenticationManager authenticationManager; 如果我用 \@Autowired 声明全局的 authenticationManager,则服务找不到它。所以我想我会走老路,用 \@Autowired ObjectPostProcessors 手动创建 authManager。感谢您的彻底回复以及您对春季安全的努力。
    • 在最新版本中,您可以通过将自定义 AuthenticationManager 公开为 Bean 来使用它
    • @RobWinch - 我想知道您是否可以评论这个问题/答案,因为您似乎知道 AuthenticationManager 内部:stackoverflow.com/a/26615970/1017787
    • 我对这个解决方案的唯一问题是我需要调用 auth.getObject() 而不是 build() 因为已经构建了管理器。感谢您解决了几天的问题。
    【解决方案2】:

    AuthenticationManager bean 的暴露和访问方式如下:

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception
    {
       return super.authenticationManagerBean();
    }
    

    【讨论】:

      猜你喜欢
      • 2013-11-16
      • 2011-01-20
      • 2015-12-28
      • 2020-04-29
      • 2012-02-03
      • 2015-09-30
      • 1970-01-01
      • 2015-07-24
      • 2013-09-18
      相关资源
      最近更新 更多