12.5.2 配置响应式用户信息服务

在扩展 WebSecurityConfigureAdapter 时,可以通过覆写 configure() 方法来声明 web 安全规则。通常通过定义 UserDetails 对象,并使用另一个 configure() 方法配置用户身份验证逻辑。重温一下,下面的代码是通过 UserDetails 的匿名实现类,使用注入的 UserRepository 对象,按用户名查找用户:

@Autowired
UserRepository userRepo;

@Override
protected void
    configure(AuthenticationManagerBuilder auth)
    throws Exception {
  auth
    .userDetailsService(new UserDetailsService() {
      @Override
      public UserDetails loadUserByUsername(String username)
                        throws UsernameNotFoundException {
        User user = userRepo.findByUsername(username)
        if (user == null) {
          throw new UsernameNotFoundException(
                  username " + not found")
        }
        return user.toUserDetails();
      }
  });
}

在这个非响应式配置中,您覆写查找用户所需的唯一方法 UserDetailsService.loadUserByUsername()。在这个方法中,您使用给定的 UserRepository,按给定用户名查找用户。如果找不到,就抛出 UsernameNotFoundException。如果找到了,就使用 toUserDetails() 返回 UserDetails 结果对象。

在响应式安全配置中,不覆写 configure() 方法,而是声明一个 ReactiveUserDetailsService 类型的 bean。ReactiveUserDetailsService 是与 UserDetailsService 等价的响应式服务。和 UserDetailsService 类似,ReactiveUserDetailsService 只需要实现一个方法。更明确地说,findByUsername() 方法要返回一个 Mono<UserDetails>,而不是原始的 UserDetails 对象。

在下面的示例中,ReactiveUserDetailsService 声明为使用给定的 UserRepository,它被认为是一个响应式的 Spring Data Repository(我们将在下一章中详细讨论):

@Service
@Bean
public ReactiveUserDetailsService userDetailsService(
                    UserRepository userRepo) {
  return new ReactiveUserDetailsService() {
    @Override
    public Mono<UserDetails> findByUsername(String username) {
      return userRepo.findByUsername(username)
        .map(user -> {
          return user.toUserDetails();
        });
    }
  };
}

这里,根据需要返回 Mono<UserDetails>,但是 UserRepository.findByUsername() 方法返回一个 Mono<User>。因为它是 Mono,您可以进行链式操作。例如通过 map() 操作把 Mono<User> 映射成 Mono<UserDetails>

在本例中,map() 操作使用 lambda 表达式的形式,通过 User 对象上的 toUserDetails() 方法,发布成 Mono。把 User 对象转换成 UserDetails 对象。因此,.map() 操作返回一个 Mono<UserDetails>,这正是 ReactiveUserDetailsService.findByUsername() 所要的。

results matching ""

    No results matching ""