0

Ich arbeite an einer Spring Boot 1.4.1 Anwendung (die einige REST-Webdienste implementiert) und ich finde einige Schwierigkeiten bei der Umsetzung Spring Security in dieses Projekt.Warum Spring Security in diesem Spring Boot REST API-Projekt nicht funktioniert? Es gibt mir immer "403 verboten" Fehler

Ich habe folgende Situation:

1) Ich habe die CustomUserDetails, die die Spring Security Userdetails-Schnittstelle implementiert:

import com.betrivius.domain.User; 
import com.betrivius.domain.UserRole; 
import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.authority.SimpleGrantedAuthority; 
import org.springframework.security.core.userdetails.UserDetails; 

public class CustomUserDetails extends User implements UserDetails { 

    private static final long serialVersionUID = 1L; 


    public CustomUserDetails(User user){ 
     super(user); 
    } 


    @Override 
    public Collection<? extends GrantedAuthority> getAuthorities() { 
     Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(); 
     for(UserRole role : this.getUserRoles()){ 
      GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getName()); 
      authorities.add(grantedAuthority); 
     } 

     return authorities; 
    } 

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

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

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

} 

2) Dann habe ich die CustomUserDetailsService die Umsetzung Spring Security UserDetailsService Schnittstelle:

import com.betrivius.dao.UserDAO; 
import com.betrivius.domain.User; 
import com.betrivius.security.bean.CustomUserDetails; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional; 

@Transactional 
@Service("customUserDetailsService") 
public class CustomUserDetailsService implements UserDetailsService{ 
    @Autowired 
    private UserDAO userDao; 

    @Override 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
     User user = userDao.findByUsername(username); 
     if(user == null){ 
      throw new UsernameNotFoundException("No user present with username: "+username); 
     }else{ 
      return new CustomUserDetails(user); 
     } 
    } 

} 

3) Zu guter Letzt muss habe ich die confinguration Klasse Spring Security WebSecurityConfig Verlängerung der WebSecurityConfigurerAdapter genannt:

import com.betrivius.security.service.CustomUserDetailsService; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 
import org.springframework.security.crypto.password.PasswordEncoder; 

@Configuration 
@EnableWebSecurity 
@ComponentScan(basePackageClasses = CustomUserDetailsService.class) 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private UserDetailsService userDetailsService; 

    @Autowired 
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder()); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests() 
       .antMatchers("/Accomodation/**").access("hasRole('ROLE_USER')") 
       .anyRequest().permitAll() 
       .and() 
       .csrf().disable(); 

    /*.and() 
    .formLogin().loginPage("/login") 
    .usernameParameter("username").passwordParameter("password") 
    .and() 
    .logout().logoutSuccessUrl("/login?logout") 
    .and() 
    .exceptionHandling().accessDeniedPage("/403") 
    .and() 
    .csrf();*/ 
    } 

    @Bean(name = "passwordEncoder") 
    public PasswordEncoder passwordencoder() { 
     return new BCryptPasswordEncoder(); 
    } 
} 

Wie Sie im vorherigen Code-Schnipsel in der Konfigurationsklasse sehen kann ich angegeben haben, dass nur Ein Benutzer mit dem ROLE_USER Setted kann auf alle Ressourcen unter dem /Accomodation/ Pfad zugreifen, ich habe es getan:

.antMatchers("/Accomodation/**").access("hasRole('ROLE_USER')") 

4) Dies ist der UserDAO dass die Benutzerinformationen verwendet, um in die vorherige CustomUserDetailsService Klasse erhalten:

@Repository 
@Transactional(propagation = Propagation.MANDATORY) 
public interface UserDAO extends JpaRepository<User, Long> { 

    User findByUsername(String username); 

    @Query("SELECT r FROM User u JOIN u.userRoles r where u.username = :username") 
    List<UserRole> findRoleByUserName(String username); 
} 

Der Benutzername und das Passwort in der DB STORD sind und sind:

BENUTZERNAME: ErSabba

PASSWORT: pswd

Benutzer Tabelle eine viele zu viele Beziehung mit User_Roles haben, die Rolle der ErSabba Benutzer ist ROLE_USER (versucht USER als Rolleneinstellung).

also von PostMan Chrome-Plugin ausführen ich eine GET-Anfrage zu der URL:

http://localhost:8080/Accomodation/7 

den vorherigen Berechtigungsnachweis auf diese Weise übergeben:

enter image description here

Wie Sie das sehen können Problem ist, dass das Einfügen des richtigen Benutzernamens und des Passworts in das grundlegende Authentifizierungsformular es gibt mir 403 Fehler Zugriff verweigert.

Ich denke, dass es bedeutet, dass ich die Authentifizierung durchführen muss, aber ich habe nicht die Genehmigung.

Die seltsame Sache ist, dass ich auch versucht habe, schlechte Anmeldeinformationen zu setzen und ich bekomme immer das gleiche anstelle 401 Bad Credential Fehler.

Ich habe auch einen Haltepunkt in dieser Zeile der loadUserByUsername() Methode in die CustomUserDetailsService Klasse setzen (die die Benutzer info abrufen).

User user = userDao.findByUsername(username); 

im Debug-Modus läuft es nicht auf dieser Linie nicht zu stoppen, so scheint es, dass Spring Security Konfiguration nicht gut funktioniert funktioniert ...

Was könnte das Problem sein? Was vermisse ich? Wie kann ich versuchen, es zu beheben?

+0

Wo generieren Sie das Authentifizierungstoken? Ich denke, dass Sie einen Authentifizierungsanbieter vermissen. –

+0

@dur ja einen Haltepunkt setzen hier stoppt es – AndreaNobili

+0

@dur Bitte können Sie mir noch ein paar zusätzliche Informationen geben, was ich genau konfigurieren muss? :-) – AndreaNobili

Antwort

0

Ich würde Ihnen empfehlen, einen Test ohne DB zu machen. Sie können eine inMemory Konfiguration, wie diese bieten:

auth.inMemoryAuthentication().withUser("ErSabba").password("pswd").authorities("ROLE_USER"); 

und versuchen dann einzuloggen. Wenn es funktioniert, wird angezeigt, dass mit den Anmeldeinformationen in der Datenbank etwas nicht stimmt.

Wie speichern Sie das Passwort in der DB? Wenn es sich um einfachen Text handelt, wird es nicht funktionieren, da Sie einen Passwort-Encoder haben, der Ihr Passwort als Hash lesen sollte.

Hoffe, dass hilft.

Verwandte Themen