iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0
自我挑戰組

Spring In Action系列 第 23

WebFlux security

  • 分享至 

  • xImage
  •  

在reactive的WebFlux Spring中若要設定security,有辦法直接使用Spring Security的類別嗎? 答案是否,因為Spring Security的前身為Acegi Security,是基於Servlet filter的架構來設計的,這在servlet中也很合理,在一個request進來以前透過filter來做security的邏輯,有通過才繼續下去。

那如果要secure WebFlux怎麼辦? 在Spring Security 5以後就有支援WebFlux了,而其介面的設計概念就是仿照Spring MVC那套來做。

在Spring MVC我們會設置如下的security config:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .antMatchers("/api", "/orders").hasAuthority("USER")
        .antMatchers("/**").permitAll();
  }
}

而在WebFlux會如下設置:

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
  @Bean
  public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
    return http
        .authorizeExchange()
          .pathMatchers("/api", "/orders").hasAuthority("USER")
          .anyExchange().permitAll()
      .and()
        .build();
  }
}

那UserDetails呢? 先來回顧一下Spring MVC的寫法:

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

而在WebFlux:

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

說實在的差別只在於一個回傳UserDetails,一個是回傳Mono,不過要進行reactive的coding通常就是透過Mono或Flux。


上一篇
Functional request handler
下一篇
Reactive persistence
系列文
Spring In Action30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言