[英]Spring security Cant autowire UserDetailsService
我在嘗試從數據庫添加身份驗證時遇到了困難。
這是錯誤日志:
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.UserDetailsService kamienica.configuration.SecurityConfig.userDetailsService; 嵌套異常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:未找到類型為 [org.springframework.security.core.userdetails.UserDetailsService] 的合格 bean 依賴項:預計至少有 1 個 bean 有資格作為此依賴項的自動裝配候選者。 依賴注釋:{@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=customUserDetailsService)} 在 org.springframework.beans.factory.annotation .AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185) 在 org.springframework. :537) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) 在 org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) 在 org.springframework .beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) 在 org.spr org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 在 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.refresh(AbstractApplication2Context.java) .springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) 在 org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) 在 org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener) .java:106) 在 org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4727) 在 org.apache.ca talina.core.StandardContext.startInternal(StandardContext.java:5167) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java: 725) 在 org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) 在 org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) 在 org.apache.catalina.startup.HostConfig .deployDescriptor(HostConfig.java:586) at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1750) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util .concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown)來源)由: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 有資格作為此依賴項的自動裝配候選者。 依賴注釋:{@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=customUserDetailsService)} 在 org.springframework.beans.factory.annotation .AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508) 在 org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) 在 org.springframework.beans. .java:289) ... 26 導致:org.springframework.beans.factory.NoSuchBeanDefinitionException:沒有找到類型為 [org.springframework.security.core.userdetails.UserDetailsService] 的合格 bean 依賴項:預計至少有 1 個 bean它有資格作為此依賴項的自動裝配候選者。 依賴注釋:{@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=customUserDetailsService)} 在 org.springframework.beans.factory.support .DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963) 在 org.springframework.beans.factory.support.DefaultListableListBeanFactory. :858) 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480) ... 28 更多
還有我的配置類:
1) 應用配置。
@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.CustomUserDetailsService] 的符合條件的依賴項:預計至少有 1 個符合此依賴項的自動裝配候選者的 bean。 依賴注解:{@org.springframework.beans.factory.annotation.Autowired(required=true)}
@Component
或@Service
和CustomUserDetailsService
,而不是兩者都使用。 如果您使用的是@Service
,那么請使用它:
@Service("userDetailsService")
現在擺脫@Qualifier。 只需使用:
@Autowired UserDetailsService userDetailsService;
我是Spring Boot的初學者,我遇到了類似的問題,但是當我為Spring認證做測試時。 我的情況:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class DefaultUserAuthenticationTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.build();
...
並收到:
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)}
當我這樣做時:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration //added this annotation
public class DefaultUserAuthenticationTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
...
異常消失了
我在這里找到解決方案。
我也面臨同樣的問題,問題是我拼錯了一個安全包。 所有包都是 com.apps.test,為了安全起見,它是 com.app.test 並且它失敗了。 請檢查您的所有包的初始值,因為在組件掃描期間,如果不相同,它將失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.