|
15 | 15 | */
|
16 | 16 | package org.springframework.security.config.web.server;
|
17 | 17 |
|
| 18 | +import static org.assertj.core.api.Assertions.assertThat; |
| 19 | +import static org.assertj.core.api.Assertions.assertThatCode; |
| 20 | +import static org.hamcrest.core.StringStartsWith.startsWith; |
| 21 | +import static org.mockito.ArgumentMatchers.any; |
| 22 | +import static org.mockito.ArgumentMatchers.anyString; |
| 23 | +import static org.mockito.Mockito.mock; |
| 24 | +import static org.mockito.Mockito.verify; |
| 25 | +import static org.mockito.Mockito.when; |
| 26 | + |
18 | 27 | import java.io.IOException;
|
19 | 28 | import java.math.BigInteger;
|
20 | 29 | import java.security.KeyFactory;
|
|
27 | 36 | import java.util.Collections;
|
28 | 37 | import java.util.stream.Collectors;
|
29 | 38 | import java.util.stream.Stream;
|
| 39 | + |
30 | 40 | import javax.annotation.PreDestroy;
|
31 | 41 |
|
32 |
| -import okhttp3.mockwebserver.MockResponse; |
33 |
| -import okhttp3.mockwebserver.MockWebServer; |
34 | 42 | import org.apache.http.HttpHeaders;
|
35 | 43 | import org.junit.Rule;
|
36 | 44 | import org.junit.Test;
|
37 | 45 | import org.junit.runner.RunWith;
|
| 46 | + |
38 | 47 | import reactor.core.publisher.Mono;
|
39 | 48 |
|
40 | 49 | import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
|
56 | 65 | import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
|
57 | 66 | import org.springframework.security.oauth2.jwt.Jwt;
|
58 | 67 | import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
| 68 | +import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; |
59 | 69 | import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
60 | 70 | import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
|
61 | 71 | import org.springframework.security.web.server.SecurityWebFilterChain;
|
62 | 72 | import org.springframework.security.web.server.authentication.HttpStatusServerEntryPoint;
|
| 73 | +import org.springframework.security.web.server.authentication.ServerAuthenticationConverter; |
63 | 74 | import org.springframework.security.web.server.authorization.HttpStatusServerAccessDeniedHandler;
|
64 | 75 | import org.springframework.test.context.junit4.SpringRunner;
|
65 | 76 | import org.springframework.test.web.reactive.server.WebTestClient;
|
|
70 | 81 | import org.springframework.web.reactive.DispatcherHandler;
|
71 | 82 | import org.springframework.web.reactive.config.EnableWebFlux;
|
72 | 83 |
|
73 |
| -import static org.assertj.core.api.Assertions.assertThat; |
74 |
| -import static org.assertj.core.api.Assertions.assertThatCode; |
75 |
| -import static org.hamcrest.core.StringStartsWith.startsWith; |
76 |
| -import static org.mockito.ArgumentMatchers.any; |
77 |
| -import static org.mockito.ArgumentMatchers.anyString; |
78 |
| -import static org.mockito.Mockito.mock; |
79 |
| -import static org.mockito.Mockito.verify; |
80 |
| -import static org.mockito.Mockito.when; |
| 84 | +import okhttp3.mockwebserver.MockResponse; |
| 85 | +import okhttp3.mockwebserver.MockWebServer; |
81 | 86 |
|
82 | 87 | /**
|
83 | 88 | * Tests for {@link org.springframework.security.config.web.server.ServerHttpSecurity.OAuth2ResourceServerSpec}
|
@@ -225,6 +230,16 @@ public void postWhenMissingTokenThenReturnsForbidden() {
|
225 | 230 | .expectStatus().isForbidden();
|
226 | 231 | }
|
227 | 232 |
|
| 233 | + @Test |
| 234 | + public void getWhenCustomBearerTokenServerAuthenticationConverterThenResponds() { |
| 235 | + this.spring.register(CustomBearerTokenServerAuthenticationConverter.class, RootController.class).autowire(); |
| 236 | + |
| 237 | + this.client.get() |
| 238 | + .cookie("TOKEN", this.messageReadToken) |
| 239 | + .exchange() |
| 240 | + .expectStatus().isOk(); |
| 241 | + } |
| 242 | + |
228 | 243 | @Test
|
229 | 244 | public void getWhenSignedAndCustomConverterThenConverts() {
|
230 | 245 | this.spring.register(CustomJwtAuthenticationConverterConfig.class, RootController.class).autowire();
|
@@ -429,6 +444,32 @@ ReactiveAuthenticationManager authenticationManager() {
|
429 | 444 | }
|
430 | 445 | }
|
431 | 446 |
|
| 447 | + @EnableWebFlux |
| 448 | + @EnableWebFluxSecurity |
| 449 | + static class CustomBearerTokenServerAuthenticationConverter { |
| 450 | + @Bean |
| 451 | + SecurityWebFilterChain springSecurity(ServerHttpSecurity http) throws Exception { |
| 452 | + // @formatter:off |
| 453 | + http |
| 454 | + .authorizeExchange() |
| 455 | + .anyExchange().hasAuthority("SCOPE_message:read") |
| 456 | + .and() |
| 457 | + .oauth2ResourceServer() |
| 458 | + .bearerTokenConverter(bearerTokenAuthenticationConverter()) |
| 459 | + .jwt() |
| 460 | + .publicKey(publicKey()); |
| 461 | + // @formatter:on |
| 462 | + |
| 463 | + return http.build(); |
| 464 | + } |
| 465 | + |
| 466 | + @Bean |
| 467 | + ServerAuthenticationConverter bearerTokenAuthenticationConverter() { |
| 468 | + return exchange -> Mono.justOrEmpty(exchange.getRequest().getCookies().getFirst("TOKEN").getValue()) |
| 469 | + .map(BearerTokenAuthenticationToken::new); |
| 470 | + } |
| 471 | + } |
| 472 | + |
432 | 473 | @EnableWebFlux
|
433 | 474 | @EnableWebFluxSecurity
|
434 | 475 | static class CustomJwtAuthenticationConverterConfig {
|
|
0 commit comments