Authentication with Spring Security + Spring data + MongoDB

不问归期 提交于 2019-12-03 02:48:20

问题


I want to use Spring security with MongoDB (using Spring data) and retrieve the users from my own database for spring security. However, I can not do that since my userservice type does not seem to be supported.

This is my UserService class:

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

And my SecurityConfig class:

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

}

The line I commented says:

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

How can I fix it so I can retrieve the users from my own database?


回答1:


Service Layer

You have to create a separate service implementing org.springframework.security.core.userdetails.UserDetailsService and inject it inside the 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 Should be also implemented. This is the POJO which will keep the user authenticated details by the Spring. You may include your Entity data object wrapped inside it, as I have done.

public class SecUserDetails implements UserDetails {

    private User user;

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

Security Config

Autowire the service that we created before and set it inside the AuthenticationManagerBuilder

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

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



回答2:


Create your own authentication provider providing a class that extends the UserDetailservice. Ensure content scanning is enable in your spring context xml file.

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

}

This class will enable spring query mongo for the username and password required for authentication. Next create the user model class.

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

Create the user implementation class that extends the 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 );
 }

Finally configure mongo and you're done.



来源:https://stackoverflow.com/questions/29606290/authentication-with-spring-security-spring-data-mongodb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!