在spring-webflux中使用spring-security时禁用WebSession创建

时间:2019-05-09 09:31:32

标签: java spring-security spring-webflux

我正在运行带有rest api的无状态spring-boot应用程序,并且想要按照https://www.baeldung.com/spring-security-session

的说明禁用WebSession的创建

我创建了自己的不存储会话的WebSessionManager。

   @Bean
   public WebSessionManager webSessionManager() {
       return new WebSessionManager() {
           @Override
           @NonNull
           public Mono<WebSession> getSession(@NonNull final ServerWebExchange exchange) {
               return Mono.just(new WebSession() {

                   @Override
                   @NonNull
                   public String getId() {
                       return "";
                   }

                   @Override
                   @NonNull
                   public Map<String, Object> getAttributes() {
                       return new HashMap<>();
                   }

                   @Override
                   public void start() {
                   }

                   @Override
                   public boolean isStarted() {
                       return true;
                   }

                   @Override
                   @NonNull
                   public Mono<Void> changeSessionId() {
                       return Mono.empty();
                   }

                   @Override
                   @NonNull
                   public Mono<Void> invalidate() {
                       return Mono.empty();
                   }

                   @Override
                   @NonNull
                   public Mono<Void> save() {
                       return Mono.empty();
                   }

                   @Override
                   public boolean isExpired() {
                       return false;
                   }

                   @Override
                   @NonNull
                   public Instant getCreationTime() {
                       return Instant.now();
                   }

                   @Override
                   @NonNull
                   public Instant getLastAccessTime() {
                       return Instant.now();
                   }

                   @Override
                   public void setMaxIdleTime(@NonNull final Duration maxIdleTime) {
                   }

                   @Override
                   @NonNull
                   public Duration getMaxIdleTime() {
                       return Duration.ofMinutes(1);
                   }
               });
           }
       };
   }

它可以工作,但是我想知道是否还有更好的方法来不创建会话。

4 个答案:

答案 0 :(得分:1)

不幸的是,Spring WebFlux尚未提供基于Spring MVC的基于STATELESS策略Issue #6552: Session Creation Policy with Webflux Security来禁用会话创建的解决方案,而且看来目前没有更多的工作要做。


除了覆盖WebSessionManager之外,您还可以禁用所有安全功能,并用自定义实现替换authenticationManagersecurityContextRepository,以去除基于会话的功能:

@Configuration
public class SecurityConfiguration {
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        // Disable default security.
        http.httpBasic().disable();
        http.formLogin().disable();
        http.csrf().disable();
        http.logout().disable();

        // Add custom security.
        http.authenticationManager(this.authenticationManager);
        http.securityContextRepository(this.securityContextRepository);

        // Disable authentication for `/auth/**` routes.
        http.authorizeExchange().pathMatchers("/auth/**").permitAll();
        http.authorizeExchange().anyExchange().authenticated();

        return http.build();
    }
}

其他信息:Spring webflux custom authentication for API

答案 1 :(得分:0)

使用为此目的专用的NoOpServerSecurityContextRepository。

@Configuration
@EnableWebFluxSecurity
@ComponentScan(value = {"my.package.security"})
public class SpringSecurityConfig2 {
    @Autowired private MyHeaderExchangeMatcher myHeaderExchangeMatcher;
    @Autowired private MyReactiveAuthenticationManager myReactiveAuthenticationManager;
    @Autowired private MyTokenAuthenticationConverter myTokenAuthenticationConverter;

    @Bean
    SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
        http.httpBasic().disable().formLogin().disable().csrf().disable().logout().disable();

        http...
                .addFilterAt(webFilter(), SecurityWebFiltersOrder.AUTHORIZATION)
                ...;

        return http.build();
    }

    @Bean
    public AuthenticationWebFilter webFilter() {
        AuthenticationWebFilter authenticationWebFilter =
                new AuthenticationWebFilter(myReactiveAuthenticationManager);
        authenticationWebFilter.setServerAuthenticationConverter(myTokenAuthenticationConverter);
        authenticationWebFilter.setRequiresAuthenticationMatcher(myHeaderExchangeMatcher);

        // NoOpServerSecurityContextRepository is used to for stateless sessions so no session or state is persisted between requests.
        // The client must send the Authorization header with every request.
        NoOpServerSecurityContextRepository sessionConfig = NoOpServerSecurityContextRepository.getInstance();

        authenticationWebFilter.setSecurityContextRepository(sessionConfig);
        return authenticationWebFilter;
    }
}

答案 2 :(得分:0)

我通过以下技巧禁用了 WebSessionManager

  @Bean
  public WebSessionManager webSessionManager() {
    // Emulate SessionCreationPolicy.STATELESS
    return exchange -> Mono.empty();
  }

所有其他解决方案对我都没有帮助。

答案 3 :(得分:-1)

您尝试过吗:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
}