Home > other >  Cannot invoke "com.smart.repository.UserRepository.getUserByUsername(String)" because &quo
Cannot invoke "com.smart.repository.UserRepository.getUserByUsername(String)" because &quo

Time:07-18

I have used spring security depedency. Getting error - Cannot invoke "com.smart.repository.UserRepository.getUserByUsername(String)" because "this.userRepository" is null .........................................................................................................................................................................................................................................................................................................................................

User -

@Entity
@Table(name = "users")
public class User {
    
    @Id
    @Column(name = "user_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String username;
    private String password;
    private boolean enabled;
    
    
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "users_roles", joinColumns = @JoinColumn (name = "user_id"), inverseJoinColumns = @JoinColumn (name="role_id"))         
    private Set<Role> roles = new HashSet<>();


    public Integer getId() {
        return id;
    }


    public void setId(Integer id) {
        this.id = id;
    }


    public String getUsername() {
        return username;
    }


    public void setUsername(String username) {
        this.username = username;
    }

    

    public String getPassword() {
        return password;
    }


    public void setPassword(String password) {
        this.password = password;
    }


    public boolean isEnabled() {
        return enabled;
    }


    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }


    public Set<Role> getRoles() {
        return roles;
    }


    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }
    
    


    @Override
    public String toString() {
        return "User [id="   id   ", username="   username   ", password="   password   ", enabled="   enabled
                  ", roles="   roles   "]";
    }


    public User() {
        super();
        // TODO Auto-generated constructor stub
    }
    
}

User Repository -

public interface UserRepository extends CrudRepository<User, Long> {

    @Query("SELECT u from User u Where u.username =:username")
    public User getUserByUsername(@Param("username") String username);  
} 

MyUserDetails -

public class MyUserDetails implements UserDetails {

    
    private User user;
    
    public MyUserDetails(User user) {
        super();
        this.user = user;
    }
    
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Set<Role> roles = user.getRoles();
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        
        for(Role role:roles) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return authorities;
    }

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

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

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

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

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

    @Override
    public boolean isEnabled() {
    
        return user.isEnabled();
    }

}

UserDetailsServiceImpl -

public class UserDetailsServiceImpl implements UserDetailsService {

    private UserRepository userRepository;
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.getUserByUsername(username);
        if(user==null) {
            throw new UsernameNotFoundException("Could not find user");
        }
        return new MyUserDetails(user);
    }

}

WebSecurityConfig -

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Bean
    public UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl();
    }
    
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService());
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
        
    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.authenticationProvider(authenticationProvider());
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.authorizeRequests()
        .antMatchers("/login").permitAll()
        .antMatchers("/").hasAnyAuthority("ADMIN","CLIENT")
        .antMatchers("/adddevice").hasAnyAuthority("ADMIN","CLIENT")
        .antMatchers("/edit/**").hasAuthority("ADMIN")
        .antMatchers("/delete/**").hasAuthority("ADMIN")

        .anyRequest().authenticated()
        .and()
        .formLogin().permitAll()
        .and()
        .logout().permitAll()
        .and()
        .exceptionHandling().accessDeniedPage("/403")
        ;
        
        http.csrf().disable();
        http.headers().frameOptions().disable();    
        }
}

CodePudding user response:

spring is not creating bean for the UserRepository as you have not annotated the class with @Repository annotation. Try annotating the class with this annotation and whenerer this class is required, consume it using @Autowired, ex-

@Autowired

private UserRepository userRepository;

Also if you want spring to inject the dependency, you will need to tell the spring to create and manage its bean using the appropriate annotations and then consume it as mentioned above.

CodePudding user response:

You never initialize UserRepository. You can either:

  1. Initilize the bean from the class and remove it from security config
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.getUserByUsername(username);
        if(user==null) {
            throw new UsernameNotFoundException("Could not find user");
        }
        return new MyUserDetails(user);
    }
}

Don't forget @Autowired on the field.

  1. Fix initialization in security config:
@Bean
@Autowired
public UserDetailsService userDetailsService(UserRepository repository) {
    return new UserDetailsServiceImpl(repository);
}

Add the contructor in UserDetailsServiceImpl:

public UserDetailsServiceImpl(UserRepository repository) {
    this.userRepository = repository;
}
  • Related