2015-04-13 16 views
15

Chcę używać zabezpieczenia Spring z MongoDB (używając danych Spring) i odzyskać użytkowników z mojej własnej bazy danych dla bezpieczeństwa wiosennego. Jednak nie mogę tego zrobić, ponieważ mój typ usługi użytkownika wydaje się nie być obsługiwany.Uwierzytelnianie za pomocą Spring Security + dane sprężyny + MongoDB

To moja klasa 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); 
    } 
} 

A moja klasa 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"); 
    } 

} 

Linia I skomentował mówi:

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

Jak mogę to naprawić, więc mogę odzyskać użytkowników z mojej własnej bazy danych?

Odpowiedz

31

Warstwa usług

Musisz utworzyć oddzielną service realizacji org.springframework.security.core.userdetails.UserDetailsService i wstrzyknąć go wewnątrz 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; 
     } 
    } 
} 

model

UserDetails Powinny być również realizowane. To jest POJO, które będzie przechowywać dane uwierzytelniane przez użytkownika na wiosnę. Możesz dołączyć obiekt danych jednostki, tak jak ja to zrobiłem.

public class SecUserDetails implements UserDetails { 

    private User user; 

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

Bezpieczeństwo Config

Autowire usługa które stworzyliśmy wcześniej i ustawić ją wewnątrz AuthenticationManagerBuilder

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

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

Specjalista ds. Bezpieczeństwa właśnie tutaj! :) Zawsze doceniam to Faraj! – Moody

+0

Bardzo dziękuję za tę odpowiedź! – zaqpiotr

+0

Czy możesz podać "import" w swojej odpowiedzi? Nie mam pojęcia o klasie użytkownika. Czy to jest niestandardowa klasa modelu? –

3

Stwórz własną dostawcy uwierzytelniania zapewniając klasę, która rozszerza UserDetailservice. Upewnij się, że skanowanie zawartości jest włączone w pliku xml kontekstu źródłowego.

<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); 
} 

}

Klasa ta pozwoli sprężyny zapytania Mongo o nazwę użytkownika i hasło wymagane do uwierzytelniania. Następnie utwórz klasę modelu użytkownika.

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; 
} 

Utwórz klasę implementacji użytkowników, która rozszerza 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); 
} 

Wreszcie skonfiguruj mongo i gotowe.

Powiązane problemy