spring-security 必须设置UserDetailsService Sping Boot 应用程序中的错误

mhd8tkvw  于 2022-11-11  发布在  Spring
关注(0)|答案(3)|浏览(332)

我有两节课
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());
}

}
和用户详细信息服务实现

@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很陌生。

j1dl9f46

j1dl9f461#

因此,我可以使用以下代码修复此问题:
对于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,spring将为您注入,因此您不必使用注解。
这是一个很好的方法,当你创建单元测试后,你可以很容易地模拟构造类进行测试。

ca1c2owp

ca1c2owp2#

我用了这个答案,它对我很有效:
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;
    }

}
siotufzp

siotufzp3#

您正在尝试在SecurityConfig中使用UserDetailServiceImpl,但是您尚未注入UserDetailServiceImpl bean,这将导致该错误。仅执行此操作是不够的:
private UserDetailServiceImpl customUserDetailsService;
您需要注入UserDetailServiceImpl bean。

相关问题