我正在运行带有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);
}
});
}
};
}
它可以工作,但是我想知道是否还有更好的方法来不创建会话。
答案 0 :(得分:1)
不幸的是,Spring WebFlux尚未提供基于Spring MVC的基于STATELESS
策略Issue #6552: Session Creation Policy with Webflux Security来禁用会话创建的解决方案,而且看来目前没有更多的工作要做。
除了覆盖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();
}
}
答案 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)
}
?