我正在尝试将 Spring Security 集成到 springMVC 应用程序中,但是创建 bean 时出现错误,尽管一切似乎都很好。
错误
org.springframework.beans.factory.UnsatisfiedDependencyException的全文:创建名称为'securityConfig'的bean时出错:通过字段'userService'表达的不满足的依赖关系;嵌套异常是 org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为 'userServiceImp' 的 bean 时出错:通过字段 'userRepository' 表达的不满足的依赖关系;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有“com.spring.repository.UserRepository”类型的合格 bean 可用:预计至少有 1 个有资格作为自动装配候选者的 bean。依赖注解:{@org.springframework.beans.factory.annotation.Autowired(required=true)}
错误中提到的类:SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserServiceImp userService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
// указываем страницу с формой логина
.loginPage("/login")
//указываем логику обработки при логине
.successHandler(new LoginSuccessHandler())
// указываем action с формы логина
.loginProcessingUrl("/login")
// Указываем параметры логина и пароля с формы логина
.usernameParameter("j_username")
.passwordParameter("j_password")
// даем доступ к форме логина всем
.permitAll();
http
.logout()
// разрешаем делать логаут всем
.permitAll()
// указываем URL логаута
.logoutRequestMatcher(new AntPathRequestMatcher("/logout", "POST"))
.invalidateHttpSession(true)
.clearAuthentication(true)
.deleteCookies("JSESSIONID")
.logoutSuccessUrl("/login")
//выклчаем кроссдоменную секьюрность (на этапе обучения неважна)
.and().csrf().disable();
http
// делаем страницу регистрации недоступной для авторизированных пользователей
.authorizeRequests()
//страницы аутентификаци доступна всем
.antMatchers("/login", "/").anonymous()
// защищенные URL
.antMatchers("/users/**").access("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
.antMatchers("/user/**").access("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
.antMatchers("/admin/**").access("hasAnyRole('ROLE_ADMIN')")
.anyRequest().authenticated();
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder());
}
}
用户服务.java
public interface UserService {
Optional<User> getUserById(Long id);
void deleteUser(Long id);
void updateUser(User user);
List<User> listUsers();
void createUser(User user);
}
UserServiceImp.java
@Service
@Transactional
public class UserServiceImp implements UserDetailsService, UserService{
@Autowired
UserRepository userRepository;
@Autowired
RoleRepository roleRepository;
@Autowired
BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
public Optional<User> getUserById(Long id) {
return userRepository.findById(id);
}
@Override
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
@Override
public void updateUser(User user) {
userRepository.save(user);
}
@Override
public List<User> listUsers() {
return userRepository.findAll();
}
@Override
public void createUser(User user) {
user.setRoles(Collections.singleton(new UserRole(1L, "ROLE_USER")));
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
userRepository.save(user);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
return user;
}
}
用户存储库.java
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
多亏了评论员,多亏了你们,我才能够找到一些可以理解的东西并最终解决了这个问题。我对程序所做的更改: