Spring WebFlux中如何修改响应的ReadOnlyHttpHeaders?遇UnsupportedOperationException
UnsupportedOperationException with ReadOnlyHttpHeaders in Spring Security Reactive
I've been stuck on this issue for an entire month with no resolution in sight. I can't find any relevant resources online, and I'm at my wit's end. I didn't configure any HTTP request headers manually, so I'm suspecting that Spring Security's default filters are setting them automatically?
Related Methods
org.springframework.web.reactive.function.server.DefaultServerResponseBuilder.AbstractServerResponse#writeToorg.springframework.web.reactive.function.server.DefaultServerResponseBuilder.AbstractServerResponse#writeStatusAndHeadersorg.springframework.web.reactive.function.server.DefaultServerResponseBuilder.AbstractServerResponse#copy
Error Message
java.lang.UnsupportedOperationException: null
at org.springframework.http.ReadOnlyHttpHeaders.putAll(ReadOnlyHttpHeaders.java:138) ~[spring-web-6.0.11.jar:6.0.11]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: ...
Relevant Code Snippets
@Override public Mono<Void> filter(@NonNull ServerWebExchange exchange, WebFilterChain chain) { return chain.filter(exchange) .contextWrite(context -> context.put(ServerHttpRequest.class, exchange.getRequest())); } @Bean public SecurityWebFilterChain serverHttpSecurity(ServerHttpSecurity security, ReactiveAuthenticationManager authenticationManager, JwtConfigProperties jwtConfigProperties) { return security .headers(ServerHttpSecurity.HeaderSpec::disable) .csrf(ServerHttpSecurity.CsrfSpec::disable) .httpBasic(ServerHttpSecurity.HttpBasicSpec::disable) .formLogin(ServerHttpSecurity.FormLoginSpec::disable) .logout(ServerHttpSecurity.LogoutSpec::disable) .authenticationManager(authenticationManager) .securityContextRepository(NoOpServerSecurityContextRepository.getInstance()) .addFilterAt(new JwtAuthenticationFilter(jwtConfigProperties), SecurityWebFiltersOrder.FIRST) .authorizeExchange(authorize -> authorize .anyExchange().permitAll() ) .build(); } @Override public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { return Mono.fromCallable(exchange::getRequest) .mapNotNull(sink -> sink.getHeaders().getFirst(HttpHeaders.AUTHORIZATION)) .filter(sink -> sink.startsWith("Bearer ")) .map(sink -> sink.substring("Bearer ".length())) .filter(StringUtils::hasText) .filter(sink -> JWTUtil.verify(sink, jwtConfigProperties.getSecret().getBytes())) .map(JWT::of) .map(sink -> { var username = sink.getPayload(RegisteredPayload.SUBJECT).toString(); var principal = User.withUsername(username) .password("rob") .build(); return new UsernamePasswordAuthenticationToken(principal, sink); }) .flatMap(sink -> chain.filter(exchange) .contextWrite(ReactiveSecurityContextHolder.withAuthentication(sink)) ) .switchIfEmpty(chain.filter(exchange)); } @PreAuthorize("isFullyAuthenticated()") public Mono<String> test2() { return Mono.just("test2"); }
Content sourced from Stack Exchange, asked by Muscidae
相关产品推荐
相关产品推荐

