Spring Security Cant自动连线UserDetailsS​​ervice


问题内容

我陷入尝试从数据库添加身份验证的过程。

这是错误日志:

2015年12月23日08:24:32.819严重[localhost-startStop-1]
org.springframework.web.context.ContextLoader.initWebApplicationContext上下文初始化失败org.springframework.beans.factory.BeanCreationException:创建名称为’securityConfig’的bean时出错:注入自动装配依赖项失败;嵌套的异常是org.springframework.beans.factory.BeanCreationException:无法自动连线字段:org.springframework.security.core.userdetails.UserDetailsS​​ervice
kamienica.configuration.SecurityConfig.userDetailsS​​ervice;
嵌套的异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有找到类型为[org.springframework.security.core.userdetails.UserDetailsS​​ervice]的合格Bean作为依赖项:至少应有1个有资格作为此依赖项的自动装配候选的bean。org.apache.catalina.startup.HostConfig
$
DeployDescriptor.run(HostConfig.java:1750)上的catalina.startup.HostConfig.deployDescriptor(HostConfig.java:586)在java.util.concurrent.Executors
$ RunnableAdapter.call(未知源)
),位于java.util.concurrent.FutureTask.run(未知源)处,位于java.util.concurrent.ThreadPoolExecutor.runWorker(未知源),位于java.util.concurrent.ThreadPoolExecutor
$ Worker.run(未知源),位于java.lang。
Thread.run(未知来源)原因:org.springframework.beans.factory.BeanCreationException:无法自动连线字段:org.springframework.security.core.userdetails.UserDetailsS​​ervice
kamienica.configuration.SecurityConfig.userDetailsS​​ervice;
嵌套的异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为[org。已找到依赖项的springframework.security.core.userdetails.UserDetailsS​​ervice]:期望至少有1个bean符合此依赖项的自动装配候选条件。依赖注释:org.springframework.beans.factory.annotation上的{@
org.springframework.beans.factory.annotation.Autowired(required = true),@
org.springframework.beans.factory.annotation.Qualifier(value =
customUserDetailsS​​ervice)}
org.springframework.beans.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)的org.springframework.beans.factory.Annotation.ProwiredProcess.Bean.Process.Beans.Factory
.java:289)…还有26个原因:org.springframework。beans.factory.NoSuchBeanDefinitionException:找不到依赖项类型为[org.springframework.security.core.userdetails.UserDetailsS​​ervice]的合格Bean:至少应有1个符合此依赖项自动候选条件的bean。依赖注释:org.springframework.beans.factory.support上的{@
org.springframework.beans.factory.annotation.Autowired(required = true),@
org.springframework.beans.factory.annotation.Qualifier(value =
customUserDetailsS​​ervice)}
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)处的org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBean。

和我的配置类:

1)AppConfig。

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "kamienica")
public class AppConfig {

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        viewResolver.setContentType("UTF-8");
        return viewResolver;
    }

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("messages");
        return messageSource;
    }

}

2)AppInitializer:

public class AppInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext container) throws ServletException {

        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(AppConfig.class);
        ctx.setServletContext(container);

        ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx));

        // added to handle local characters
        FilterRegistration.Dynamic fr = container.addFilter("encodingFilter", new CharacterEncodingFilter());
        fr.setInitParameter("encoding", "UTF-8");
        fr.setInitParameter("forceEncoding", "true");
        fr.addMappingForUrlPatterns(null, true, "/*");

        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");

    }

}

现在最重要的部分是:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("customUserDetailsService")
    UserDetailsService userDetailsService;

    //
    // @Autowired
    // CustomSuccessHandler customSuccessHandler;
    //
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/", "/index").permitAll().antMatchers("/Admin/**")
                .access("hasRole('ADMIN')").antMatchers("/User/**").access("hasRole('ADMIN') or hasRole('USER')")
                // .and().formLogin().loginPage("/login")
                .and().formLogin()
                // .loginPage("/login")
                // .successHandler(customSuccessHandler)
                // .usernameParameter("email").passwordParameter("password")
                // .and().csrf()
                // .and().exceptionHandling().accessDeniedPage("/Access_Denied")
        ;
    }
}

我的自定义用户服务:

@Component
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    TenantService tenantService;

    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {

        Tenant tenant = tenantService.loadByMail(email);

        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority(tenant.getRole()));
        return new org.springframework.security.core.userdetails.User(tenant.getEmail(), tenant.getPassword(), true,
                true, true, true, authorities);
    }

}

我在这里做错了什么?

编辑1.我已经修改了以下文件中的注释,但没有解决问题:

@Service("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    TenantService tenantService;

    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {

        Tenant tenant = tenantService.loadByMail(email);

        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority(tenant.getRole()));
        return new org.springframework.security.core.userdetails.User(tenant.getEmail(), tenant.getPassword(), true,
                true, true, true, authorities);
    }

}

和:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;

    //
    // @Autowired
    // CustomSuccessHandler customSuccessHandler;
    //
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/", "/index").permitAll().antMatchers("/Admin/**")
                .access("hasRole('ADMIN')").antMatchers("/User/**").access("hasRole('ADMIN') or hasRole('USER')")
                // .and().formLogin().loginPage("/login")
                .and().formLogin()
                // .loginPage("/login")
                // .successHandler(customSuccessHandler)
                // .usernameParameter("email").passwordParameter("password")
                // .and().csrf()
                // .and().exceptionHandling().accessDeniedPage("/Access_Denied")
        ;
    }
}

编辑2:根据塞尔瓦的建议:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    CustomUserDetailsService customUserDetailsService;

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService);
        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/", "/index").permitAll().antMatchers("/Admin/**")
                .access("hasRole('ADMIN')").antMatchers("/User/**").access("hasRole('ADMIN') or hasRole('USER')")
                .and().formLogin();
    }
}

不幸的是,结果相同:

找不到依赖项类型为[kamienica.service.CustomUserDetailsS​​ervice]的合格Bean:期望至少有1个有资格作为该依赖项的自动装配候选的bean。依赖项注释:{@
org.springframework.beans.factory.annotation.Autowired(required = true)}


问题答案:
  1. @Component@Service与一起使用,或CustomUserDetailsService两者都不用。
  2. 如果您正在使用@Service,则可以像这样使用它:

@Service("userDetailsService")

  1. 现在摆脱@Qualifier。只需使用:

@Autowired UserDetailsService userDetailsService;