我有两个类(class)
安全配置.java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private UserDetailServiceImpl customUserDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
和 UserDetailsServiceImpl
@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Autowired
private UserRepository repository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User currentUser = repository.findByUsername(username);
UserDetails user = new org.springframework.security.core.userdetails.User(
username,
currentUser.getPassword(),
true,
true,
true,
true,
AuthorityUtils.createAuthorityList(currentUser.getRole()));
return user;
}
日志错误:
Caused by: java.lang.IllegalArgumentException: A UserDetailsService must be set
at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.doAfterPropertiesSet(DaoAuthenticationProvider.java:100)
根据文档,错误可能来自于此:
Throws:IllegalArgumentException - if a null value was passed either as a parameter or as an element in the GrantedAuthority collection
属性设置不正确可能... 那么如何设置 UserDetailsService 呢?如何修复此错误?这个例子取自这本书,但它可能太旧了,有些东西发生了变化。我对 Spring 很陌生。
最佳答案
所以我能够使用以下方法解决此问题:
对于 SecurityConfig.java:
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private UserDetailServiceImpl customUserDetailsService;
//Spring injecting for you, IoC
public SecurityConfig(UserDetailServiceImpl customUserDetailsService) {
this.customUserDetailsService = customUserDetailsService;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() //We don't need CSRF for this example
.authorizeRequests()
.anyRequest().authenticated() // all request requires a logged in user
.and()
.formLogin()
.loginProcessingUrl("/login") //the URL on which the clients should post the login information
.usernameParameter("username") //the username parameter in the queryString, default is 'username'
.passwordParameter("password");
}
}
在这里,您可以配置请求登录的 url,以及对于表单,如果您想自定义登录 url、用户名和密码字段。
你的主要问题是,你没有在你的类中注入(inject)“UserDetailServiceImpl”。
这里提示:你可以像我上面那样使用构造函数而不是使用@Autowired,spring 会为你注入(inject),所以你不必使用注解。
在您创建单元测试之后,这是一个很好的方法,您可以在构建要测试的类时轻松模拟。
关于spring - 必须在 Spring Boot 应用程序中设置 UserDetailsService 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57041979/