2017-01-08 5 views
2

Ich bin ein Neuling, um die Sicherheit zu erhöhen und die Federsicherheit in meiner Spring-Boot-Webanwendung zu implementieren. Ich folge SpringSecurity Blog, um Sicherheit durch user und role mithilfe der Datenbank zu implementieren. Der Code wurde auch bei github gefunden. Dieser Blog sagtRepository gibt null in Spring Security zurück


Hinweis

Wir werden die Bohne UserRepository zum UserDetailsService geben, da diese Bohne geladen werden, bevor das Repository geladen wird, so könnten wir die useeRepository Bohne als null in erhalten aus SSUserDetailsService.


N. B: Ich habe Änderung SSUserDetailsService-WebUserDetailsService

Ich habe

Entity:User und Role schafft 3-Tabellen (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 zu holen Daten aus der Datenbank

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

    User findByUsername(String username); 

} 

Sicherheitskonfiguration: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 

Probleme:

  1. userRepository.findByUsername() gibt null für gültige Anmeldeinformationen in WebUserDetailsService>loadUserByUsername() zurück. Ich habe beobachtet, dass, wenn ich den folgenden Code (User user = userRepository.findByUsername(username); Linie) als Testzweck setzen Sie dann sah, dass es keinen Fehler für die Validierung gibt. Das ist userRepository funktioniert nicht. Was soll ich tun, um einen Benutzer mit dem Benutzernamen userRepository zu ziehen?

    @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. Ich nenne userRepository.findByUsername() in meiner "/" URL-Zuordnung zu testen, ob Repository arbeitet oder nicht. Ich habe herausgefunden, dass ein Fehler für toString() in User gemeldet wurde.Es gibt keinen Fehler, wenn ich die Zeile ", roles=" + roles + auskommentiert habe. Wie lade ich Rolle mit dem entsprechenden Benutzer? Werfen Sie einen Blick auf toString() in Benutzer

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

Gibt es ein Problem, viele-zu-viele-Mapping? – Johir

+0

getRoles gibt nichts zurück, solange Benutzer userRepository.findByUsername() gefunden hat. Warum? – Johir

Antwort

0

ein data.sql erstellen und legen Sie sie in Ihrem src/main/resources Ordner. Es muss mindestens folgenden Inhalt haben.

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

Nicht gelöst! ... sollte ich .antMatchers ("/ user/**"). hasAuthority ("USER") zu .antMatchers ("/ user/**") ändern. hasAuthority ("ROLE_USER")? bitte schauen Sie auf 'application.properties' Datei auch @shazin – Johir

+0

SOLVES! ... Ich habe gerade auskommentieren "", users = "+ users +" -Zeile in toString() in der Rolle Klasse. Ich denke, Rollenanrufbenutzer und Benutzeranrufrolle (Rollenbenutzerrolle) und bildet eine Endlosschleife. – Johir

Verwandte Themen