2015-04-13 22 views
15

Desidero utilizzare la sicurezza Spring con MongoDB (utilizzando i dati Spring) e recuperare gli utenti dal mio database per la sicurezza Spring. Tuttavia, non posso farlo poiché il mio tipo di servizio utenti non sembra essere supportato.Autenticazione con Spring Security + Spring data + MongoDB

Questa è la mia classe UserService:

public class UserService { 
    private ApplicationContext applicationContext; 
    private MongoOperations mongoOperations; 

    public UserService() { 
     applicationContext = new AnnotationConfigApplicationContext(MongoConfig.class); 
     mongoOperations = (MongoOperations) applicationContext.getBean("mongoTemplate"); 
    } 

    public User find(String username) { 
     return mongoOperations.findOne(Query.query(Criteria.where("username").is(username)), User.class); 
    } 
} 

E la mia classe SecurityConfig:

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
    @Autowired 
    UserService userService; 

    @Autowired 
    public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception { 
     builder.userDetailsService(userService); //THIS DOES NOT WORK 
     builder.inMemoryAuthentication().withUser("username").password("password").roles("USER"); 
    } 

} 

La linea ho commentato dice:

The inferred type UserService is not a valid substitute for the bounded parameter <T extends UserDetailsService>. 

Come posso risolvere il problema in modo da poter recuperare gli utenti dal mio database?

risposta

31

Service Layer

È necessario creare un separato service attuazione org.springframework.security.core.userdetails.UserDetailsService e iniettare all'interno del AuthenticationManagerBuilder.

@Component 
public class SecUserDetailsService implements UserDetailsService{ 

    @Autowired 
    private UserRepository userRepository; 

    @Override 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
     /*Here add user data layer fetching from the MongoDB. 
      I have used userRepository*/ 
     User user = userRepository.findByUsername(username); 
     if(user == null){ 
      throw new UsernameNotFoundException(username); 
     }else{ 
      UserDetails details = new SecUserDetails(user); 
      return details; 
     } 
    } 
} 

Modello

UserDetails dovrebbero anche essere implementato. Questo è il POJO che manterrà i dettagli autentificati dall'utente dalla Primavera. È possibile includere l'oggetto dati Entity avvolto al suo interno, come ho fatto io.

public class SecUserDetails implements UserDetails { 

    private User user; 

    public SecUserDetails(User user) { 
     this.user = user; 
    } 
    ...... 
    ...... 
    ...... 
} 

Security Config

Autowire il servizio che abbiamo creato prima e metterlo dentro la AuthenticationManagerBuilder

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
    @Autowired 
    SecUserDetailsService userDetailsService ; 

    @Autowired 
    public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception { 
     builder.userDetailsService(userDetailsService); 
    } 
} 
+2

Esperto di sicurezza proprio lì! :) Apprezzo sempre Faraj! – Moody

+0

Uomo grazie mille per questa risposta! – zaqpiotr

+0

Puoi includere "importazioni" anche nella tua risposta? Sono confuso sulla classe User. È una classe modello personalizzata? –

3

Create il vostro provider di autenticazione che fornisce una classe che estende l'UserDetailservice. Assicurarsi che la scansione del contenuto sia abilitata nel file xml del contesto di primavera.

<authentication-provider user-service-ref="userModelService"> 
     <password-encoder hash="sha" /> 
    </authentication-provider> 

@Service 
public class UserModelService implements UserDetailsService 
{ 
@Autowired 
private UserModelRepositoryImpl repository; 



public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 
{ 
    UserModel user = repository.findByUsername(username); 

    if(user == null) 
     throw new UsernameNotFoundException("Name not found!"); 

     List<SimpleGrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority(user.getRole())); 

     return new User(user.getUsername(), user.getSHA1Password(), authorities); 
} 

public void saveUserDetails(UserModel userModel) 
{ 
    repository.save(userModel); 
} 

}

Questa classe permetterà primavera interrogazione Mongo per il nome utente e la password richiesti per l'autenticazione. Quindi creare la classe del modello utente.

public class UserModel 
{ 

private String id; 
@Indexed(unique=true) 
private String username; 
private String password; 
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; 
} 

Creare la classe di implementazione utente che estende DAO.

@Service 
public class UserModelService implements UserDetailsService 
{ 
@Autowired 
private UserModelRepositoryImpl repository; 



public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 
{ 
    UserModel user = repository.findByUsername(username); 

    if(user == null) 
     throw new UsernameNotFoundException("Oops!"); 

     List<SimpleGrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority(user.getRole())); 

     return new User(user.getUsername(), user.getSHA1Password(), authorities); 
} 

Infine configura mongo e il gioco è fatto.

Problemi correlati