Saya baru mengenal spring boot dan spring security dan tidak dapat memahami kesalahan berikut sendiri. aplikasi boot musim semi saya hanya berisi dua URL satu yang diakses oleh siapa saja yaitu, hanya dengan nama siapa kata sandi disimpan dalam database dan yang lain yang hanya dapat diakses oleh ADMIN (untuk menambahkan pengguna dan ada roll di database MySql). Tetapi ketika saya melewati nama pengguna dan kata sandi itu mengatakan: -

org.springframework.security.authentication.InternalAuthenticationServiceException: UserDetailsService returned null, which is an interface contract violation

Saya memposting semua kelas yang diperlukan di bawah ini:-

CustomUserDetailService:-

@Service
public class CustomUserDetailService implements UserDetailsService {

    @Autowired
    private UserRepository repository;

    @Override
    public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {

        User user= repository.findByname(name);
        CustomUserDetail userDetail=null;
        if(user!=null){
            CustomUserDetail userDetails=new CustomUserDetail();
            userDetails.setUser(user);
        }else{
            throw new UsernameNotFoundException("User not exist with name :" +name);
        }
            return null;
    }
}

CustomUserDetail

public class CustomUserDetail implements UserDetails {

    private User user;

    /*Getter and Setter*/

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    /*Overriden methods from userDetail*/

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("Role_"+role))
                .collect(Collectors.toList());
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getName();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

BasicConfig:-

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class BasicConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.userDetailsService(userDetailsService).passwordEncoder(encodePWD());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.csrf().disable();
        http
                .authorizeRequests()
                     .antMatchers("/user/").permitAll()
                     .and()
                .authorizeRequests()
                     .antMatchers("/MiniApi/**").hasAnyRole("ADMIN")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .permitAll();
    }

    @Bean
    public BCryptPasswordEncoder encodePWD()
    {
        return new BCryptPasswordEncoder();
    }
}

Kelas Pengontrol:- Saya tidak membuat dua kelas @Restcontroller dan hanya satu @RequestMapping() yang bertindak sebagai URL dasar

AdminController:-

@RestController
@RequestMapping("/MiniApi")
public class Admincontroller
{
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @PreAuthorize("hasAnyRole('ADMIN')")
    @PostMapping("/admin/add")
    public String addUser(@RequestBody User user)
    {
        String pwd = user.getPassword();
        String encryptPwd = passwordEncoder.encode(pwd);
        user.setPassword(encryptPwd);
        userRepository.save(user);
        return "User added successfully...";
    }
}

Siapa Saja:-

public class AnyOne {

    @GetMapping("/anyone")
    public String Anyone()
    {
        return "processing......";
    }
}

Ubah apa yang saya buat:- Jika saya menghapus pernyataan pengembalian dari CustomUserDetailService, saya mendapatkan kesalahan pernyataan pengembalian hilang dan kemudian saya menambahkan return userDetails; itu memberi saya: -

Pertama ia meminta saya untuk nama pengguna dan kata sandi saya memberikannya dan kemudian ini

Status HTTP 403 – Dilarang

0
deep 23 Juli 2020, 21:23

1 menjawab

Jawaban Terbaik
  • Anda mengembalikan null alih-alih userDetails
    @Service
    public class CustomUserDetailService implements UserDetailsService {

      @Autowired
      private UserRepository repository;

      @Override
      public UserDetails loadUserByUsername(String name) throws 
                UsernameNotFoundException {

        User user= repository.findByname(name);
        CustomUserDetail userDetail=null;
        if(user != null){
            CustomUserDetail userDetails=new CustomUserDetail();
            userDetails.setUser(user);
            return userDetails;
        } 
        throw new 
            UsernameNotFoundException("User not exist with name :" +name);

            
      }
    }  
1
Kavithakaran Kanapathippillai 23 Juli 2020, 20:57