ReactorContextWebFilter preserves main Context

Previously ReactorContextWebFilter overrode
the main Context.

Fixes: gh-4962
This commit is contained in:
Rob Winch 2018-02-08 14:58:08 -06:00
parent c399987450
commit 141e3f581f
2 changed files with 31 additions and 2 deletions

View File

@ -22,6 +22,7 @@ import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import reactor.util.context.Context;
/**
* @author Rob Winch
@ -39,8 +40,12 @@ public class ReactorContextWebFilter implements WebFilter {
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange)
.subscriberContext(c -> c.hasKey(SecurityContext.class) ? c :
Mono.defer(() -> this.repository.load(exchange))
.as(ReactiveSecurityContextHolder::withSecurityContext)
withSecurityContext(c, exchange)
);
}
private Context withSecurityContext(Context mainContext, ServerWebExchange exchange) {
return mainContext.putAll(Mono.defer(() -> this.repository.load(exchange))
.as(ReactiveSecurityContextHolder::withSecurityContext));
}
}

View File

@ -22,12 +22,19 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
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.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextImpl;
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.test.StepVerifier;
import reactor.util.context.Context;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
@ -98,4 +105,21 @@ public class ReactorContextWebFilterTests {
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();
}
}