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:
- 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.
- 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;
}