2017-01-08 4 views
2

Я новичок в безопасности весны и пытаюсь реализовать весеннюю безопасность в своем веб-приложении весенней загрузки. Я следую за блоком SpringSecurity для обеспечения безопасности через user и role с использованием базы данных. Код также найден в github. Этот блог говоритРепозиторий возвращает значение null в Spring Security


Примечание

Мы будем передавать боб UserRepository к UserDetailsService, потому что этот компонент будет загружен перед загрузкой в ​​хранилище, так что мы могли бы получить useeRepository боба утратившего в out SSUserDetailsService.


N.B: У меня есть изменение SSUserDetailsService к WebUserDetailsService

У меня есть

Entity:User и Role создает 3 таблицы (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 для извлечения данных из базы данных

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

    User findByUsername(String username); 

} 

настройки безопасности: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; 
    } 

} 

Связь с базами данных: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 

Проблемы:

  1. userRepository.findByUsername() возвращает null для действительных учетных данных в WebUserDetailsService>loadUserByUsername(). Я заметил, что если я поставлю следующий код (комментируя строку User user = userRepository.findByUsername(username);) в качестве цели тестирования, то увидел, что для проверки не существует ошибки. То есть userRepository не работает. Что делать, чтобы вытащить пользователя по имени пользователя, используя 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. Я называю userRepository.findByUsername() в моем отображении "/" URL, чтобы проверить, является ли хранилище работать или нет. Я понял, что есть ошибка для toString(), заявленная в User.Нет ошибки, если я прокомментировал строку ", roles=" + roles +. Как загрузить роль с соответствующим пользователем? Посмотрите на ToString() в пользовательском

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

Есть ли проблема в отображении многих-ко-многим? – Johir

+0

getRoles ничего не возвращает, пока пользователь пользователь найден пользователемRepository.findByUsername(). Зачем? – Johir

ответ

0

Создать data.sql и поместить его в папку src/main/resources. Он должен иметь минимум минимум.

INSERT INTO user(username, password, enabled) VALUES('[email protected]', 'abc123', true); 

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

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

Не разрешено! ... следует изменить .antMatchers («/ user/**»). hasAuthority («USER») для .antMatchers («/ user/**»). hasAuthority («ROLE_USER»)? пожалуйста, посмотрите файл 'application.properties' также @shazin – Johir

+0

РЕШЕНИЯ! ... Я просто прокомментировал '', users = "+ users +" строку в toString() в классе ролей. Я думаю, Роль вызовет пользователя и Роль пользователя (Роль-Пользователь-Роль) и сформирует бесконечный цикл. – Johir