有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在使用springsecurity和springwebflux时禁用WebSession创建

我正在运行一个带有rest api的无状态spring启动应用程序,并希望禁用WebSessions的创建,如https://www.baeldung.com/spring-security-session

我创建了自己的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);
                   }
               });
           }
       };
   }

它是有效的,但我想知道是否有更好的方法不创建会话


共 (2) 个答案

  1. # 1 楼答案

    你试过:

    @Configuration
    @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    }
    

    ?

  2. # 2 楼答案

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

    The problem is that the request cache is being invoked for every request to see if there is a value saved to replay and thus the WebSession is being looked up for every request. Since the WebSession is being looked up with an invalid session id, Spring WebFlux invalidates the SESSION cookie. ~ rwinch

    I created gh-7157 to limit when the request cache is being accessed (and thus the WebSession). In the meantime if you don't need the request cache, you can disable it using:

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

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

    此外DarrenJiang1990建议更完整的解决方案:

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

    The security context in a WebFlux application is stored in a ServerSecurityContextRepository. Its WebSessionServerSecurityContextRepository implementation, which is used by default, stores the context in session. Configuring a NoOpServerSecurityContextRepository instead would make our application stateless


    (以前的解决方法)

    除了覆盖WebSessionManager之外,您还可以禁用所有安全功能并替换authenticationManager&securityContextRepository 通过自定义实现剥离基于会话的功能:

    @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