简体   繁体   中英

Repository returns null in Spring Security

I am newbie to spring security and trying to implement spring security in my spring-boot web application. I am following SpringSecurity blog to implement security through user and role using database. The code also found at github . This blog says


Note

We will pass the bean UserRepository to the UserDetailsService because this bean will be loaded before the repository is loaded, so we might get the useeRepository bean as null in out SSUserDetailsService.


NB: I have change SSUserDetailsService to WebUserDetailsService

I have

Entity: User and Role creates 3 tables ( user , role & user_roles )

/*------------------------------------- User entity -------------------------------------*/
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String username;
    private String password;
    private boolean enabled;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;

    // getters, setters & toString

}


/*------------------------------------- Role entity -------------------------------------*/
@Entity
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String role;

    @ManyToMany(mappedBy = "role", fetch = FetchType.LAZY)
    private Set<User> users;

    //getters, setters & toString 

}

Repository: UserRepository to fetch data from database

/*----------------------------------- User repository ----------------------------------*/
@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    User findByUsername(String username);

}

Security Configuration: WebSecurityConfigurer & WebUserDetailsService

/*------------------------------- WebSecurityConfigurer -------------------------------*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserRepository userRepository;

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

    @Override
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return new WebUserDetailsService(userRepository);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .antMatchers("/css/**", "/img/**", "/js/**").permitAll()
                    .antMatchers("/", "/home").permitAll()
                    .antMatchers("/admin/**").hasAuthority("ADMIN")
                    .antMatchers("/user/**").hasAuthority("USER")
                    .anyRequest().authenticated()
                .and()
                    .formLogin()
                        .loginPage("/login")
                            .usernameParameter("username").passwordParameter("password").permitAll()
                .and()
                    .logout()
                        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                        .logoutSuccessUrl("/")
        ;
    }

}



/*------------------------------- WebUserDetailsService -------------------------------*/
@Transactional
public class WebUserDetailsService implements UserDetailsService {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(WebUserDetailsService.class);

    private UserRepository userRepository;

    public WebUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try {
            User user = userRepository.findByUsername(username);
            if (user == null) {
                LOGGER.debug("user not found with the provided username");
                return null;
            }
            LOGGER.debug(" user from username " + user.toString());
            return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthorities(user));
        }
        catch (Exception e){
            throw new UsernameNotFoundException("User not found");
        }
    }

    private Set<GrantedAuthority> getAuthorities(User user){
        Set<GrantedAuthority> authorities = new HashSet<>();
        for(Role role : user.getRoles()) {
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getRole());
            authorities.add(grantedAuthority);
        }
        LOGGER.debug("user authorities are " + authorities.toString());
        return authorities;
    }

}

Database Connectivity: application.properties

#defauls
#security.user.name=user
#security.user.password=password
#security.user.role=ROLE_USER, ROLE_ADMIN

#configurations
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext

#initializations
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false

#credentials
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/spring_boot_security
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.schema=classpath:/data/schema.sql

#query-configurations
spring.datasource.maxActive=10
spring.datasource.max-idle=4
spring.datasource.min-idle=2
spring.datasource.test-while-idle=true
spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1
spring.datasource.time-between-eviction-runs-millis=60000
spring.datasource.min-evictable-idle-time-millis=300000

#server-configurations
hazelcast.server.address=127.0.0.1

Problems:

  1. userRepository.findByUsername() returns null for valid credentials in WebUserDetailsService > loadUserByUsername() . I observed that if I put following code (commenting out User user = userRepository.findByUsername(username); line) as test purpose then saw that there is no error for validation. That is userRepository is not working. What should I do to pull a user by username using userRepository ?

     @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { try { //User user = userRepository.findByUsername(username); Role role = new Role(); role.setId(1L); role.setRole("USER"); Set<Role> roles = new HashSet<>(); roles.add(role); User user = new User(); user.setEnabled(true); user.setId(1L); user.setPassword("12345"); user.setUsername("johir1"); user.setRoles(roles); if (user == null) { LOGGER.debug("user not found with the provided username"); return null; } LOGGER.debug(" user from username " + user.toString()); return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthorities(user)); } catch (Exception e){ throw new UsernameNotFoundException("User not found"); } } 
  2. I call userRepository.findByUsername() in my "/" URL mapping to test whether repository is working or not. I figured out there is an error for toString() declared in User . There is no error if I commented out ", roles=" + roles + line. How do I load role with corresponding user? Have a look at toString() in User

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

Create a data.sql and place it in your src/main/resources folder. It must have the following content at minimum.

INSERT INTO user(username, password, enabled) VALUES('abc@bca.com', 'abc123', true);

INSERT INTO role(role) VALUES('ROLE_USER');

INSERT INTO user_roles(user_id, role_id) VALUES(1, 1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM