我正在使用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);
                   }
               });
           }
       };
   }


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

最佳答案

Issue #6552: Session Creation Policy with Webflux Security将由Spring团队修复。


  问题在于,正在为每个请求调用请求缓存,以查看是否保存了要重播的值,因此正在为每个请求查找WebSession。由于正在使用无效的会话ID查找WebSession,因此Spring WebFlux使SESSION cookie无效。 〜rwinch
  
  我创建了gh-7157,以限制何时访问请求缓存(以及WebSession)。同时,如果您不需要请求缓存,则可以使用以下命令禁用它:


http
.requestCache()
    .requestCache(NoOpServerRequestCache.getInstance());


您可以在Issue #7157 ServerRequestCacheWebFilter causes WebSession to be read every request中跟踪修补进度。

另外,DarrenJiang1990建议使用更完整的解决方案:

.and().securityContextRepository(NoOpServerSecurityContextRepository.getInstance())



  WebFlux应用程序中的安全上下文存储在ServerSecurityContextRepository中。默认情况下使用的WebSessionServerSecurityContextRepository实现将上下文存储在会话中。相反,配置NoOpServerSecurityContextRepository将使我们的应用程序变为无状态




(以前的解决方法)

除了覆盖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

关于java - 在spring-webflux中使用spring-security时禁用WebSession创建,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56056404/

10-12 14:22