我有2个课程
SecurityConfig.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)
来自docs的错误可能来自于此:
Throws:IllegalArgumentException - if a null value was passed either as a parameter or as an element in the GrantedAuthority collection
属性设置不正确可能... 那么如何设置UserDetailsService呢?如何解决此错误?这个例子是从书中摘下来的,但是它可能太旧了,有些东西改变了。我是Spring的新手。
答案 0 :(得分:2)
所以我可以使用以下方法解决此问题:
对于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,用户名和密码字段,请配置表单。
您的主要问题是,您没有在类中注入“ UserDetailServiceImpl”。
这里的提示:您可以像上面一样使用@Autowired构造函数,并且弹簧将为您注入,因此您不必使用注释。
这是创建单元测试之后的好方法,并且在构造要测试的类时可以轻松地进行模拟。
答案 1 :(得分:0)
我用了这个答案,对我有用:
https://stackoverflow.com/a/42191609/1010619
@EnableWebSecurity
@Configuration
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService;
public AppSecurityConfig(UserDetailsService userDetailsService) {
super();
this.userDetailsService = userDetailsService;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder builder, PasswordEncoder passwordEncoder) throws Exception {
builder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
// @formatter:off
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/webjars/**", "/static/**").permitAll()
.antMatchers("/", "/index", "/home", "/register", "/user/confirmRegistration").permitAll()
.antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/loginCustom").permitAll().loginProcessingUrl("/doLogin")
.and()
.logout().permitAll().logoutUrl("/logout").logoutSuccessUrl("/")
.and()
.csrf().disable()
;
}// @formatter:on
public UserDetailsService getUserDetailsService() {
return userDetailsService;
}
@Autowired
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
}