Hi I have a problem with Autowired UsrDetailsService, I found that many others have the same problem but no other solution works for me (and I dont know why) I use java configuration (no xml)
Error code
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'securityConfig':
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private com.mycompany.delivery.service.AccountServiceImpl com.mycompany.delivery.config.SecurityConfig.accUserDetailsService;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.mycompany.delivery.service.AccountServiceImpl] 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), @org.springframework.beans.factory.annotation.Qualifier(value=accUserDetailsService)}
When I Autowired this class to Controller, or anywhere else it works fine, everything else is autowiring fine as well only to WebSecurityConfigurerAdapter I cant.
My Security config:
Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("accUserDetailsService")
private AccountServiceImpl accUserDetailsService;
public AccountServiceImpl getAccUserDetailsService() {
return accUserDetailsService;
}
public void setAccUserDetailsService(AccountServiceImpl accUserDetailsService) {
this.accUserDetailsService = accUserDetailsService;
}
// @Override
// protected void configure(AuthenticationManagerBuilder registry) throws Exception {
// registry.userDetailsService(accUserDetailsService);
//}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("mkyong").password("123456").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
auth.inMemoryAuthentication().withUser("dba").password("123456").roles("DBA");
}
//.csrf() is optional, enabled by default, if using WebSecurityConfigurerAdapter constructor
@Bean(name = "myAuthenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/admin/**").access("hasRole('ROLE_USER')")
.antMatchers("/admin/partlyVisible/**").access("hasAnyRole('ROLE_USER', 'ROLE_ADMIN')").and()
.formLogin().loginPage("/admin/login").failureUrl("/admin/login?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/admin/login?logout").and()
.exceptionHandling().accessDeniedPage("/admin/403")
.and()
.csrf();
}
}
My WebMvcConfigurerAdapter
@Configuration
@EnableWebMvc
@Import({ SecurityConfig.class })
@ComponentScan(basePackages = "com.mycompany.*")
@ImportResource({"classpath:applicationContext.xml"})
@EnableTransactionManagement
public class MySpringMvcConfig extends WebMvcConfigurerAdapter {
final static Logger log = LoggerFactory.getLogger(MySpringMvcConfig.class);
/**
* Maps the main page to a specific view.
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
log.debug("mapping URL / to home view");
registry.addViewController("/").setViewName("home");
registry.addViewController("/snoop").setViewName("snoop");
}
/**
* Enables default Tomcat servlet that serves static files.
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
log.debug("enabling default servlet for static files");
configurer.enable();
}
/**
* Provides mapping from view names to JSP pages in WEB-INF/jsp directory.
*/
@Bean
public ViewResolver viewResolver() {
log.debug("registering JSP in /WEB-INF/jsp/ as views");
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
/**
* Provides localized messages.
*/
@Bean
public MessageSource messageSource() {
log.debug("registering ResourceBundle 'Texts' for messages");
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("Texts");
return messageSource;
}
/**
* Provides JSR-303 Validator.
*/
@Bean
public Validator validator() {
log.debug("validator()");
return new LocalValidatorFactoryBean();
}
}
AbstractAnnotationConfigDispatcherServletInitializer
public class MyStartInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
private Object sc;
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
//create Spring beans context configured in MySpringMvcConfig.class
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(MySpringMvcConfig.class);
ctx.register(SecurityConfig.class);
//register Spring MVC main Dispatcher servlet
ServletRegistration.Dynamic disp = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
disp.setLoadOnStartup(1);
disp.addMapping("/");
//register filter setting utf-8 encoding on all requests
FilterRegistration.Dynamic encoding = servletContext.addFilter("encoding", CharacterEncodingFilter.class);
encoding.setInitParameter("encoding", "utf-8");
encoding.addMappingForUrlPatterns(null, false, "/*");
//register bundle also for JSTL fmt: tags which are not behind DispatcherServlet
servletContext.setInitParameter(Config.FMT_LOCALIZATION_CONTEXT, "Texts");
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { MySpringMvcConfig.class, SecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
AbstractSecurityWebApplicationInitializer
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
public SpringSecurityInitializer() {
super(SecurityConfig.class);
}
}
And last my UserDetailsService
@Service(value = "accUserDetailsService")
public class AccountServiceImpl implements UserDetailsService {
@Autowired
private AccountDAO accountDao;
public AccountDAO getAccountDao() {
return accountDao;
}
public void setAccountDao(AccountDAO accountDao) {
this.accountDao = accountDao;
}
@Override
public UserDetails loadUserByUsername(String string) throws UsernameNotFoundException {
UserDetails userDetails = null;
Account account = accountDao.getByLogin(string);
if (account == null) {
throw new UsernameNotFoundException("Account not found.");
}
userDetails = new AccountAdapter(account);
return userDetails;
}
}
Thanks for helping
After another hour i made it work (but not sure how/why)
My Security config:
@Configuration
@EnableWebSecurity
change to
@Configuration
@EnableWebMvcSecurity
@ImportResource({"classpath:applicationContext.xml"})
@EnableGlobalMethodSecurity
where ImportResource is important, but now i have importrecource twice, first time here second time in WebMvcConfigurerAdapter
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With