我试图从数据库添加身份验证时遇到困难 .
这是错误日志:
23-Dec-2015 08:24:32.819 SEVERE [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.UserDetailsService kamienica.configuration.SecurityConfig.userDetailsService;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到类型为[org.springframework.security.core.userdetails.UserDetailsService]的限定bean依赖:预期至少有1个bean符合此依赖关系的autowire候选者 . org.springframework.beans.factory.annotation中的依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true),@ org.springframework.beans.factory.annotation.Qualifier(value = customUserDetailsService)} .AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java :537)org.springframework上org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:302)的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) org.spr中的.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ingframe.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)位于org.springframework.beans.factory.support的org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) . org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)中的org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)中的DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703) .springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener) .java:106)org.apache.ca上的org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4727) talina.core.StandardContext.startInternal(StandardContext.java:5167)org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java: 725)org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)atg.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)at org.apache.catalina.startup.HostConfig .deployDescriptor(HostConfig.java:586)atg.apache.catalina.startup.HostConfig $ DeployDescriptor.run(HostConfig.java:1750)at java.util.concurrent.Executors $ runnableAdapter.call(Unknown Source)at 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.UserDetailsService kamienica.configuration.SecurityConfig.userDetailsService;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到类型为[org.springframework.security.core.userdetails.UserDetailsService]的限定bean依赖:预期至少有1个bean符合此依赖关系的autowire候选者 . org.springframework.beans.factory.annotation中的依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true),@ org.springframework.beans.factory.annotation.Qualifier(value = customUserDetailsService)} .AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)在org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor .java:289)... 26更多引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:否为依赖项找到[org.springframework.security.core.userdetails.UserDetailsService]类型的限定bean:预期至少有1个bean可以作为此依赖项的autowire候选者 . org.springframework.beans.factory.support中的依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true),@ org.springframework.beans.factory.annotation.Qualifier(value = customUserDetailsService)} .defaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103)org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java) :858)org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)... 28更多
我的配置类:
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);
}
}
我在这做错了什么?
EDIT 1. I have modified the annotations in the files below but it did not solve the issue:
@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")
;
}
}
EDIT 2: As per Selva's suggestion:
@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.CustomUserDetailsService]的限定bean用于依赖:预期至少有1个bean符合此依赖关系的autowire候选者 . 依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}
2 回答
使用
@Component
或@Service
与CustomUserDetailsService
,而不是两者 .如果您使用
@Service
,请使用它,如:@Service("userDetailsService")
@Autowired UserDetailsService userDetailsService;
我是Spring Boot的初学者,我遇到了类似的问题,但是当我为Spring认证做测试时 . My case:
and received:
org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为'some.package.myClass.DefaultUserAuthenticationTest'的bean时出错:通过字段'webApplicationContext'表示的不满意的依赖关系;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为'org.springframework.web.context.WebApplicationContext'的限定bean可用:预期至少有1个bean可以作为autowire候选者 . 依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}
When i did that:
exception disappeared
我找到了解决方案here .