Spring-boot OAuth2 实现:NoSuchBeanDefinitionException:没有 AuthenticationManager 类型的合格 bean

Posted

技术标签:

【中文标题】Spring-boot OAuth2 实现:NoSuchBeanDefinitionException:没有 AuthenticationManager 类型的合格 bean【英文标题】:Spring-boot OAuth2 implementation: NoSuchBeanDefinitionException: No qualifying bean of type AuthenticationManager 【发布时间】:2019-02-04 13:16:48 【问题描述】:

org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为“authorizationServerConfig”的 bean 时出错:不满意 通过字段“authenticationManager”表示的依赖关系;嵌套的 例外是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 符合条件的 bean 类型 'org.springframework.security.authentication.AuthenticationManager' 可用:预计至少有 1 个符合 autowire 条件的 bean 候选人。依赖注解: @org.springframework.beans.factory.annotation.Autowired(required=true)

您好,我有 spring-boot web 应用程序,我正在尝试按照以下示例使用 Spring Security 和 OAuth2 实现登录/授权-身份验证系统:https://www.youtube.com/watch?v=dTAgI_UsqMg&t=1307s

一切都很好,但是当我运行我的应用程序时,我得到一个异常,说它无法为 AuthenticationManager 找到 bean,甚至认为它在那里并且自动装配。

在互联网上查看这似乎是 Oauth2 的一个已知或常见问题,但我找不到正确的解决方法

有些人建议“公开” AuthenticationManager bean,我不确定在这种情况下这意味着什么

这是我在 github 上当前项目的链接:https://github.com/chenchi13/spring-boot-cms

谁能帮我解决这个问题?

抛出异常的类:

@EnableResourceServer
@Configuration                                                      
public class ResourceServerConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private UserDetailsService customUserDetailService;

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http.requestMatchers()
                .antMatchers("/login", "/oauth/authorize")
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .permitAll();
    


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 

        //auth.parentAuthenticationManager(authenticationManager)
        //        .inMemoryAuthentication()
        //        .withUser("Peter")
        //        .password("peter")
        //        .roles("USER");

        auth.parentAuthenticationManager(authenticationManager)
                .userDetailsService(customUserDetailService);
    

授权服务器配置:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter 

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception 

        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    


    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception 
        clients
                .inMemory()
                .withClient("ClientId")
                .secret("secret")
                .authorizedGrantTypes("authorization_code")
                .scopes("user_info")
                .autoApprove(true);
    


    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception 

        endpoints.authenticationManager(authenticationManager);
    

【问题讨论】:

【参考方案1】:

ResourceServerConfig中删除以下内容:

@Autowired
private AuthenticationManager authenticationManager;

并更改配置方法如下:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.userDetailsService(customUserDetailService);

同样覆盖ResourceServerConfig中的以下方法:

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

这应该可以解决您的问题。

【讨论】:

嗨,确实修复了这个异常,但我得到了另一个异常:工厂方法'springSecurityFilterChain'抛出异常;嵌套异常是 java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException... 这与此有关还是另一个问题? p.s.感谢您的回复... 看来您使用的是 Java 9 或更高版本。在您的 maven 或 gradle 文件中添加以下依赖项 javax.xml.bindjaxb-api2.3.0 现在我明白了:嵌套异常是 java.lang.RuntimeException:javax.xml.bind.JAXBException:在模块路径或类路径上未找到 JAXB-API 的实现...确定找到在这里回答这个问题:***.com/questions/43574426/…【参考方案2】:

我认为您缺少authenticationManager bean 的定义。我正在添加以下几行,请检查一次:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter 

   // Other Details

   @Bean
   @Override
   protected AuthenticationManager authenticationManager() throws Exception 
      return super.authenticationManager();
   

   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception 
      auth.userDetailsService(userDetailsService)
              .passwordEncoder(new ShaPasswordEncoder(encodingStrength));
   

   @Override
   protected void configure(HttpSecurity http) throws Exception 
      http
              .sessionManagement()
              .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
              .and()
              .httpBasic()
              .realmName(securityRealm)
              .and()
              .csrf()
              .disable();

   

 // Other Details


您可以通过下面的参考链接。

参考:Spring Boot with JWT and OAuth2.0

希望对你有帮助:)

【讨论】:

以上是关于Spring-boot OAuth2 实现:NoSuchBeanDefinitionException:没有 AuthenticationManager 类型的合格 bean的主要内容,如果未能解决你的问题,请参考以下文章

让 oauth2 与 spring-boot 和 rest 一起工作

将 OAuth2 添加到 spring-boot 时出现 CSRF-token 错误

如何使用spring-boot 1.3.0.RC1为oauth2提供自定义安全性配置

使用 Twitch 进行身份验证时的 Spring-Boot OAuth2 奇怪行为

spring-boot oauth2 拆分授权服务器和资源服务器

微服务和 Spring Security OAuth2