Ошибка создания bean-компонента webSecurityConfig через поле неудовлетворенной зависимости userDetailsService
Я работаю над приложением Spring-Boot, корзиной для покупок. Кажется, все в порядке, соединение с MySQL работает, JDBC загружен, но я всегда получу исключение, я не могу найти решение.
Кажется, что интерфейс UserDetailsService не работает должным образом. Должен сказать, что я использую устаревший спящий метод Query for Pagination Results. Может ли это быть причиной? Помощь приветствуется после нескольких часов поиска. Понятия не имею Спасибо....
Исключение:
2018-03-19 18:44:23.192 WARN 10956 --- [main]
ConfigServletWebServerApplicationContext :
Exception encountered during context initialization - cancelling
refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'webSecurityConfig':
Unsatisfied dependency expressed through field 'userDetailsService';
nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'userDetailsService':
Unsatisfied dependency expressed through field 'accountDAO';
nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'accountDAO':
Unsatisfied dependency expressed through field 'sessionFactory';
nested exception is
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'sessionFactory'
defined in com.maxmaxy.mangoshop.SpringBootMangoShopApplication:
Bean instantiation via factory method failed;
nested exception is
org.springframework.beans.BeanInstantiationException:
Failed to instantiate [org.hibernate.SessionFactory]:
Factory method 'getSessionFactory' threw exception;
nested exception is org.hibernate.MappingException:
Failed to scan classpath for unlisted classes
pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-
8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
WebSecurityConfig:
import org.springframework.beans.factory.annotation.Autowired;
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.
WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.
BCryptPasswordEncoder;
import com.maxmaxy.mangoshop.service.UserDetailsServiceImpl;
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws
Exception {
// Set service to find User in the database & set password encoder
BCryptPasswordEncoder bcryptPasswordEncoder = new
BCryptPasswordEncoder();
auth.userDetailsService(userDetailsService).passwordEncoder
(bcryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
//Requires login with role EMPLOYEE or MANAGER. If not, will
redirect to /admin/login
http.authorizeRequests()
.antMatchers("/admin/orderList","/admin/order",
"/admin/accountInfo")
.access("hasAnyRole('ROLE_EMPLOYEE', 'ROLE_MANAGER'");
// Pages only for Manager
http.authorizeRequests().antMatchers("/admin/product")
.access("hasRole('ROLE_MANAGER')");
// When user login, role XX accessDeniedException
http.authorizeRequests().and().exceptionHandling()
.accessDeniedPage("/403");
//Configuration for login form
http.authorizeRequests().and().formLogin()
// Submit the Url
.loginProcessingUrl("/j_spring_security_check")
.loginPage("/admin/login")
.defaultSuccessUrl("/admin/accountInfo")
.failureUrl("/admin/login?error=true")
.usernameParameter("userName")
.passwordParameter("password")
// Configuration for the logout page
.and().logout().logoutUrl("/admin/logout")
.logoutSuccessUrl("/");
}
}
UserDetailsServiceImpl:
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority
.SimpleGrantedAuthority;
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;
import org.springframework.stereotype.Service;
import com.maxmaxy.mangoshop.dao.AccountDAO;
import com.maxmaxy.mangoshop.entity.Account;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private AccountDAO accountDAO;
@Override
public UserDetails loadUserByUsername(String username) throws
UsernameNotFoundException {
Account account = accountDAO.findAccount(username);
System.out.println("Account= " + account);
if (account == null) {
throw new UsernameNotFoundException("User " //
+ username + " was not found in the database");
}
// EMPLOYEE,MANAGER,..
String role = account.getUserRole();
List<GrantedAuthority> grantList =
new ArrayList<GrantedAuthority>();
// ROLE_EMPLOYEE, ROLE_MANAGER
GrantedAuthority authority = new SimpleGrantedAuthority(role);
grantList.add(authority);
boolean enabled = account.isActive();
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
UserDetails userDetails = (UserDetails) new
User(account.getUserName(), //
account.getEncryptedPassword(), enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, grantList);
return userDetails;
}
}
И последний упомянутый класс в исключении AccountDAO:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.maxmaxy.mangoshop.entity.Account;
@Transactional
@Repository
public class AccountDAO {
@Autowired
private SessionFactory sessionFactory;
public Account findAccount(String userName) {
Session session = this.sessionFactory.getCurrentSession();
return session.find(Account.class, userName);
}
}
1 ответ
Я думаю, что с пружинными данными проще загружать их в Maven, и это хороший шаг, теперь вы должны его использовать. не создавайте свой репозиторий на основе фабрики сессий, но на основе данных о весне, как это.
@Repository public interface AccountRepository extends
JpaRepository<AccountEntity, String> {
AccountEntity findByEmail(String username);
AccountEntity findByName(String name);
}
Теперь вы можете @AutoWired его, где вы хотите (вам не нужно никаких реализаций, он понимает, что AccountEntity является сущностью, и он имеет адрес электронной почты и имя в качестве атрибута, и вам нужно искать по ним ^^)
хорошо документировано, если вам нужно другое будущее