ReactorContextWebFilter preserves main Context
Previously ReactorContextWebFilter overrode the main Context. Fixes: gh-4962
This commit is contained in:
parent
c399987450
commit
141e3f581f
|
@ -22,6 +22,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||||
import org.springframework.web.server.WebFilter;
|
import org.springframework.web.server.WebFilter;
|
||||||
import org.springframework.web.server.WebFilterChain;
|
import org.springframework.web.server.WebFilterChain;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.util.context.Context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
|
@ -39,8 +40,12 @@ public class ReactorContextWebFilter implements WebFilter {
|
||||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||||
return chain.filter(exchange)
|
return chain.filter(exchange)
|
||||||
.subscriberContext(c -> c.hasKey(SecurityContext.class) ? c :
|
.subscriberContext(c -> c.hasKey(SecurityContext.class) ? c :
|
||||||
Mono.defer(() -> this.repository.load(exchange))
|
withSecurityContext(c, exchange)
|
||||||
.as(ReactiveSecurityContextHolder::withSecurityContext)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Context withSecurityContext(Context mainContext, ServerWebExchange exchange) {
|
||||||
|
return mainContext.putAll(Mono.defer(() -> this.repository.load(exchange))
|
||||||
|
.as(ReactiveSecurityContextHolder::withSecurityContext));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,19 @@ import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||||
|
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.core.context.SecurityContextImpl;
|
import org.springframework.security.core.context.SecurityContextImpl;
|
||||||
import org.springframework.security.test.web.reactive.server.WebTestHandler;
|
import org.springframework.security.test.web.reactive.server.WebTestHandler;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
import org.springframework.web.server.WebFilter;
|
||||||
|
import org.springframework.web.server.WebFilterChain;
|
||||||
|
import org.springframework.web.server.handler.DefaultWebFilterChain;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
import reactor.util.context.Context;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
@ -98,4 +105,21 @@ public class ReactorContextWebFilterTests {
|
||||||
|
|
||||||
verify(this.repository).load(any());
|
verify(this.repository).load(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
// gh-4962
|
||||||
|
public void filterWhenMainContextThenDoesNotOverride() {
|
||||||
|
String contextKey = "main";
|
||||||
|
WebFilter mainContextWebFilter = (e, c) -> c
|
||||||
|
.filter(e)
|
||||||
|
.subscriberContext(Context.of(contextKey, true));
|
||||||
|
|
||||||
|
WebFilterChain chain = new DefaultWebFilterChain(e -> Mono.empty(), mainContextWebFilter, this.filter);
|
||||||
|
Mono<Void> filter = chain.filter(MockServerWebExchange.from(this.exchange.build()));
|
||||||
|
StepVerifier.create(filter)
|
||||||
|
.expectAccessibleContext()
|
||||||
|
.hasKey(contextKey)
|
||||||
|
.then()
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue