java - 将 spring-security 与 spring-webflux 一起使用时禁用 WebSession 创建
问题描述
我正在运行一个带有 rest api 的无状态 spring-boot 应用程序,并希望按照https://www.baeldung.com/spring-security-session的描述禁用 WebSessions 的创建
我创建了自己的不存储会话的 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);
}
});
}
};
}
它有效,但我想知道是否有更好的方法来不创建会话。
解决方案
问题 #6552:具有 Webflux 安全性的会话创建策略将由Spring 团队修复。
问题是每个请求都会调用请求缓存,以查看是否有保存的值要重播,因此正在为每个请求查找 WebSession。由于使用无效会话 ID 查找 WebSession,因此 Spring WebFlux 使 SESSION cookie 无效。~绞盘
我创建了 gh-7157 来限制何时访问请求缓存(以及 WebSession)。同时,如果您不需要请求缓存,可以使用以下方法禁用它:
http
.requestCache()
.requestCache(NoOpServerRequestCache.getInstance());
您可以在问题 #7157 ServerRequestCacheWebFilter 中跟踪修补的进度,导致 WebSession 被读取每个请求。
另外DarrenJiang1990建议更完整的解决方案:
.and().securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
WebFlux 应用程序中的安全上下文存储在 ServerSecurityContextRepository 中。其默认使用的 WebSessionServerSecurityContextRepository 实现将上下文存储在会话中。配置 NoOpServerSecurityContextRepository 将使我们的应用程序无状态
(以前的解决方法)
除了覆盖之外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();
}
}
更多信息:API 的 Spring webflux 自定义身份验证 。
推荐阅读
- python - 尝试更新 Python 3.9 给出错误
- c++ - How to define a non blocking input in C++
- javascript - return 语句中的 JavaScript 赋值
- android - Write the logcat in a txt file on a phone application
- javascript - Connecting to Zookeeper from client-side javascript
- macos - Fiddler everyone doesn't capture traffic
- java - 如何在 gradle 中以编程方式从 src/java 中排除顶级包?
- sql - 基于 FOR LOOP 在 SQL Query 中使用 PLSQL 变量
- azure - 如何在 Azure Cosmos DB 中设置时区?
- laravel - SQLSTATE [42S02] 工匠修补程序的问题