无法自动装配字段:私有 org.springframework.security.authentication.AuthenticationManager

Posted

技术标签:

【中文标题】无法自动装配字段:私有 org.springframework.security.authentication.AuthenticationManager【英文标题】:Could not autowire field: private org.springframework.security.authentication.AuthenticationManager 【发布时间】:2016-10-24 13:17:04 【问题描述】:

我正在尝试使用本教程 Spring OAuth2 创建 OAuth2 服务器提供程序。示例和我的项目之间的主要区别 - 我不使用 Spring Boot。我尝试拆分这些类 (GitHub example link) 我创建了 2 个类:

@Configuration
@Order(-20)
@EnableResourceServer
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

  @Autowired
  private AuthenticationManager authenticationManager;

  @Override
  protected void configure(HttpSecurity http) throws Exception 
    http.formLogin().loginPage("/login").permitAll()
            .and()
            .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
            .and()
            .authorizeRequests().anyRequest().authenticated();
  

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.parentAuthenticationManager(authenticationManager);
  

二等:

@Configuration
@EnableAuthorizationServer
@EnableResourceServer
public class OAuth2AuthorizationConfiguration extends AuthorizationServerConfigurerAdapter 

  @Autowired
  private AuthenticationManager authenticationManager;

  @Bean
  public JwtAccessTokenConverter jwtAccessTokenConverter() 
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    KeyPair keyPair = new KeyStoreKeyFactory(
            new ClassPathResource("keystore.jks"), "foobar".toCharArray())
            .getKeyPair("test");
    converter.setKeyPair(keyPair);
    return converter;
  

  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception 
    clients.inMemory()
            .withClient("acme")
            .secret("acmesecret")
            .authorizedGrantTypes("authorization_code", "refresh_token",
                    "password").scopes("openid").autoApprove(true).accessTokenValiditySeconds(30);


  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception 
    endpoints.authenticationManager(authenticationManager).accessTokenConverter(
            jwtAccessTokenConverter());
  

  @Override
  public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception 
    oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess(
            "isAuthenticated()");
  


但是当我尝试启动这段代码时,我得到:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'OAuth2AuthorizationConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private   org.springframework.security.authentication.AuthenticationManager com.example.configuration.security.OAuth2AuthorizationConfiguration.authenticationManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: @org.springframework.beans.factory.annotation.Autowired(required=true)
at   org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5066)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5584)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1863)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:618)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:565)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:324)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.authentication.AuthenticationManager com.example.configuration.security.OAuth2AuthorizationConfiguration.authenticationManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: @org.springframework.beans.factory.annotation.Autowired(required=true)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
... 58 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: @org.springframework.beans.factory.annotation.Autowired(required=true)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 60 more

我想,问题出在我的应用程序中没有使用的 Spring Boot 中。 我尝试了以下解决方案:First,Second 我只使用基于代码的配置。 附加信息: 爪哇 8 spring-security-oauth2 - 2.0.7.RELEASE, spring-security-version - 4.0.1.RELEASE, 春季版本 - 4.0.6.RELEASE。

如何解决?

更新

我创造了

@Configuration
public class AuthManager extends WebSecurityConfigurerAdapter 

    @Bean
    public AuthenticationManager customAuthenticationManager() throws Exception 
        return authenticationManager();
    


现在我有例外:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.authentication.AuthenticationManager org.com.example.configuration.security.WebSecurityConfig.authenticationManager; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'customAuthenticationManager': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
    ... 100 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'customAuthenticationManager': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)

OAuth2AuthorizationConfiguration 类中的此异常。

【问题讨论】:

这个讨论可能会有所帮助 - github.com/spring-projects/spring-boot/issues/11136 【参考方案1】:

创建另一个WebSecurityConfigurerAdapter 类作为“主”配置并添加以下代码以公开AuthenticationManager bean:

@Bean
public AuthenticationManager customAuthenticationManager() throws Exception 
  return authenticationManager();

【讨论】:

我已经添加了这个,因为我在我的测试环境中遇到了同样的错误。这解决了我的测试环境,但我无法登录我有 401 错误。 为什么有必要这样做?【参考方案2】:

解决方案:只需删除protected void configure(AuthenticationManagerBuilder auth) 方法。根据 javadoc 我不需要这个方法。

【讨论】:

【参考方案3】:

添加 bean 后,您应该从 authenticationManager 中删除 @Autowired

  private AuthenticationManager authenticationManager;
  @Bean
  public AuthenticationManager customAuthenticationManager() throws Exception 
      return authenticationManager();
  

【讨论】:

【参考方案4】:

在您的 servlet-context.xml 中添加这一行

<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

【讨论】:

【参考方案5】:

在您扩展 WebSecurityConfigurerAdapter 的同一类中,添加以下代码

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

【讨论】:

以上是关于无法自动装配字段:私有 org.springframework.security.authentication.AuthenticationManager的主要内容,如果未能解决你的问题,请参考以下文章

单元测试 Spring MVC web-app:无法自动装配字段:私有 javax.servlet.ServletContext

具有自动装配的字段但得到无法自动装配字段消息

注入自动装配的依赖项失败,无法自动装配字段

创建 bean 时出错。注入自动装配的依赖项失败。无法自动装配字段

Spring框架的新手收到此错误:无法自动装配字段:

无法自动装配字段:不能到 com.sun.proxy.$Proxy22