ServerWebExchangeReactorContextWebFilter

Fixes: gh-5779
This commit is contained in:
Rob Winch 2018-09-05 16:11:36 -05:00
parent 65c81ce952
commit 07b6699fd9
2 changed files with 41 additions and 0 deletions

View File

@ -133,6 +133,7 @@ import org.springframework.web.cors.reactive.DefaultCorsProcessor;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.util.context.Context;
import static org.springframework.security.web.server.DelegatingServerAuthenticationEntryPoint.DelegateEntry;
import static org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher.MatchResult.match;
@ -1098,6 +1099,7 @@ public class ServerHttpSecurity {
}
sortedWebFilters.add(f);
});
sortedWebFilters.add(0, new ServerWebExchangeReactorContextWebFilter());
return new MatcherSecurityWebFilterChain(getSecurityMatcher(), sortedWebFilters);
}
@ -2191,4 +2193,15 @@ public class ServerHttpSecurity {
+ '}';
}
}
/**
* Workaround https://jira.spring.io/projects/SPR/issues/SPR-17213
*/
static class ServerWebExchangeReactorContextWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange)
.subscriberContext(Context.of(ServerWebExchange.class, exchange));
}
}
}

View File

@ -27,12 +27,16 @@ import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.config.annotation.web.reactive.ServerHttpSecurityConfigurationBuilder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.test.web.reactive.server.WebTestClientBuilder;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.WebFilterChainProxy;
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
import org.springframework.test.web.reactive.server.EntityExchangeResult;
import org.springframework.test.web.reactive.server.FluxExchangeResult;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.test.publisher.TestPublisher;
@ -117,9 +121,33 @@ public class ServerHttpSecurityTests {
.expectBody().isEmpty();
}
@Test
public void buildWhenServerWebExchangeFromContextThenFound() {
SecurityWebFilterChain filter = this.http.build();
WebTestClient client = WebTestClient.bindToController(new SubscriberContextController())
.webFilter(new WebFilterChainProxy(filter))
.build();
client.get().uri("/foo/bar")
.exchange()
.expectBody(String.class).isEqualTo("/foo/bar");
}
private WebTestClient buildClient() {
WebFilterChainProxy springSecurityFilterChain = new WebFilterChainProxy(
this.http.build());
return WebTestClientBuilder.bindToWebFilters(springSecurityFilterChain).build();
}
@RestController
private static class SubscriberContextController {
@GetMapping("/**")
Mono<String> pathWithinApplicationFromContext() {
return Mono.subscriberContext()
.filter(c -> c.hasKey(ServerWebExchange.class))
.map(c -> c.get(ServerWebExchange.class))
.map(e -> e.getRequest().getPath().pathWithinApplication().value());
}
}
}