【问题标题】:Authentication with Spring Security + Spring data + MongoDB使用 Spring Security + Spring 数据 + MongoDB 进行身份验证
【发布时间】:2015-06-18 19:41:27
【问题描述】:

我想将 Spring 安全性与 MongoDB 一起使用(使用 Spring 数据)并从我自己的数据库中检索用户以实现 Spring 安全性。但是,我不能这样做,因为我的用户服务类型似乎不受支持。

这是我的 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);
    }
}

还有我的 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");
    }

}

我评论的那行说:

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

我该如何解决它,以便我可以从我自己的数据库中检索用户?

【问题讨论】:

    标签: java spring mongodb spring-security mongodb-java


    【解决方案1】:

    创建您自己的身份验证提供程序,提供一个扩展 UserDetailservice 的类。 确保在您的 spring 上下文 xml 文件中启用内容扫描。

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

    }

    这个类将为认证所需的用户名和密码启用spring查询mongo。接下来创建用户模型类。

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

    创建扩展 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 );
     }
    

    最后配置好 mongo 就大功告成了。

    【讨论】:

      【解决方案2】:

      服务层

      您必须创建一个单独的 service 实现 org.springframework.security.core.userdetails.UserDetailsService 并将其注入到 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;
              }
          }
      }
      

      型号

      UserDetails 也应该实现。这是 POJO,它将通过 Spring 保留用户经过身份验证的详细信息。您可以像我所做的那样将您的 Entity 数据对象包含在其中。

      public class SecUserDetails implements UserDetails {
      
          private User user;
      
          public SecUserDetails(User user) {
              this.user = user;
          }
          ......
          ......
          ......
      }
      

      安全配置

      自动装配我们之前创建的服务并将其设置在AuthenticationManagerBuilder

      @Configuration
      @EnableWebSecurity
      public class SecurityConfig extends WebSecurityConfigurerAdapter {
          @Autowired
          SecUserDetailsService userDetailsService ;
      
          @Autowired
          public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception {
              builder.userDetailsService(userDetailsService); 
          }
      }
      

      【讨论】:

      • 安全专家就在身边! :) 永远感谢法拉杰!
      • 您能否在答案中也包含“imports”?我对用户类感到困惑。这是一个自定义模型类吗?
      猜你喜欢
      • 2019-05-29
      • 1970-01-01
      • 2016-01-11
      • 2012-11-27
      • 2013-12-16
      • 2014-07-03
      • 2018-08-09
      • 2012-11-10
      相关资源
      最近更新 更多