Je veux utiliser la sécurité Spring avec MongoDB (en utilisant les données Spring) et récupérer les utilisateurs de ma propre base de données pour la sécurité Spring. Cependant, je ne peux pas faire cela car mon type de service utilisateur ne semble pas être pris en charge.
Voici ma 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);
}
}
Et ma 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 ligne que j'ai commentée dit:
The inferred type UserService is not a valid substitute for the bounded parameter <T extends UserDetailsService>.
Comment puis-je le corriger pour pouvoir récupérer les utilisateurs de ma propre base de données?
Couche de service
Vous devez créer un service
implémentant org.springframework.security.core.userdetails.UserDetailsService
et l'injecter dans le 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;
}
}
}
Modèle
UserDetails
Doit également être implémenté. Il s'agit du POJO qui conservera les détails authentifiés de l'utilisateur au printemps. Vous pouvez inclure votre objet de données Entity enveloppé à l'intérieur, comme je l'ai fait.
public class SecUserDetails implements UserDetails {
private User user;
public SecUserDetails(User user) {
this.user = user;
}
......
......
......
}
Configuration de sécurité
Câbler automatiquement le service que nous avons créé auparavant et le placer dans le AuthenticationManagerBuilder
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
SecUserDetailsService userDetailsService ;
@Autowired
public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(userDetailsService);
}
}
Créez votre propre fournisseur d'authentification en fournissant une classe qui étend le service UserDetailservice. Assurez-vous que l'analyse du contenu est activée dans votre fichier xml de contexte de printemps.
<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);
}
}
Cette classe activera spring query mongo pour le nom d'utilisateur et le mot de passe requis pour l'authentification. Créez ensuite la classe de modèle utilisateur.
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;
}
Créez la classe d'implémentation utilisateur qui étend le 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 );
}
Enfin, configurez mongo et vous avez terminé.