Reputation: 4480
I'm getting a NoSuchBeanDefinitionException for the @Autowired AccountRepository in the code below with the error message: No qualifying bean of type [com.brahalla.PhotoAlbum.dao.AccountRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
. I have added the package containing the repository to @ComponentScan but for some reason it is still not seeing it. Dependency injection works everywhere else in my project, just not in this particular file.
package com.brahalla.PhotoAlbum.configuration;
import com.brahalla.PhotoAlbum.dao.AccountRepository;
import com.brahalla.PhotoAlbum.domain.entity.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@Configuration
@ComponentScan("com.brahalla.PhotoAlbum.dao")
public class GlobalAuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
@Autowired
AccountRepository accountRepository;
@Override
public void init(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService());
}
@Bean
UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Account account = accountRepository.findByUsername(username);
if(account != null) {
return new User(
account.getUsername(),
account.getPassword(),
true, true, true, true,
AuthorityUtils.createAuthorityList("USER")
);
} else {
throw new UsernameNotFoundException("could not find the user '" + username + "'");
}
}
};
}
}
And here is the repository:
package com.brahalla.PhotoAlbum.dao;
import com.brahalla.PhotoAlbum.domain.entity.Account;
import org.springframework.data.repository.CrudRepository;
public interface AccountRepository extends CrudRepository<Account, Long> {
public Account findByUsername(String username);
}
And the main application config:
package com.brahalla.PhotoAlbum.configuration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ApplicationConfiguration {
public static void main(String[] args) {
SpringApplication.run(ApplicationConfiguration.class, args);
}
}
Here's the full log and stack trace: http://pastebin.com/PKvd8rXV
EDIT Here is the git repository, the code in question is in branch develop
.
Upvotes: 1
Views: 6476
Reputation: 4096
I faced the same issue this issue is exactly due to the Spring Boot ApplicationConfiguration.java being created inside a specific package than in the root. I moved it to root It worked fine.
i.e initially it was in com.myproject.root.config, i moved it to com.myproject.root
Upvotes: 0
Reputation: 4480
I discovered the solution to the problem, and I just wanted to make sure that I posted it here.
First of all, I moved all of the web configuration options to a single class which extends WebSecurityConfigurerAdapter. Second, I had to change the annotation for the AuthenticationManagerBuilder initialization to @Autowired instead of @Override. Third, I had to make the UserDetailsService bean public:
package com.brahalla.PhotoAlbum.configuration;
import com.brahalla.PhotoAlbum.dao.AccountRepository;
import com.brahalla.PhotoAlbum.domain.entity.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
AccountRepository accountRepository;
@Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(userDetailsService());
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.anyRequest().fullyAuthenticated()
//.and().authorizeUrls()
/*.and().formLogin()
.loginPage("/login")
.permitAll()
.and().logout()
.permitAll()*/
.and().httpBasic()
.and().csrf()
.disable();
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Account account = accountRepository.findByUsername(username);
if(account != null) {
return new User(
account.getUsername(),
account.getPassword(),
true, true, true, true,
AuthorityUtils.createAuthorityList("USER")
);
} else {
throw new UsernameNotFoundException("could not find the user '" + username + "'");
}
}
};
}
}
Upvotes: 1
Reputation: 21
1) Could you try to put your class ApplicationConfiguration
class in the root package com.brahalla.PhotoAlbum
instead of com.brahalla.PhotoAlbum.configuration
?
Actually, @SpringBootApplication
scans subpackages of where it's located.
See Reference Guide 14.2 Locating the main application class
2) As other said, put @EnableJpaRepositories
at your class GlobalAuthenticationConfiguration
With this two configurations, it should work
Upvotes: 0
Reputation: 29266
Can you try with below snippet :
package com.brahalla.PhotoAlbum.dao;
import com.brahalla.PhotoAlbum.domain.entity.Account;
import org.springframework.stereotype.Repository;
import org.springframework.data.repository.CrudRepository;
@Repository
public interface AccountRepository extends CrudRepository<Account, Long> {
public Account findByUsername(String username);
}
Also, annotate your ApplicationConfiguration
with @EnableJpaRepositories
Upvotes: 0
Reputation: 13
Can you post debug logs of the application?. It will give an idea whether the bean was created. Try to place componentscan in applicationconfiguration class and mark GlobalAuthenticationConfiguration with @component or relevant annotation
Upvotes: 0
Reputation: 3512
I think you're missing @EnableJpaRepositories
in your ApplicationConfiguration
class.
Upvotes: 0
Reputation: 1481
The classes with annotations like @controller,@service,@component, @Repository etc will be the candidates for auto wiring and the other classes are not.so consider annotating your class accordingly for proper auto wiring.
@Component --> generic stereotype for any Spring-managed component
@Repository--> stereotype for persistence layer
@Service --> stereotype for service layer
@Controller --> stereotype for presentation layer (spring-mvc)
The following code should work
@Repository
public interface AccountRepository extends CrudRepository<Account, Long> {
public Account findByUsername(String username);
}
Upvotes: 3