27
27
28
28
import okhttp3 .mockwebserver .MockResponse ;
29
29
import okhttp3 .mockwebserver .MockWebServer ;
30
+ import org .assertj .core .api .InstanceOfAssertFactories ;
30
31
import org .junit .jupiter .api .AfterEach ;
31
32
import org .junit .jupiter .api .Test ;
32
33
import reactor .netty .http .HttpResources ;
43
44
import org .springframework .boot .actuate .endpoint .EndpointId ;
44
45
import org .springframework .boot .actuate .endpoint .annotation .Endpoint ;
45
46
import org .springframework .boot .actuate .endpoint .annotation .ReadOperation ;
46
- import org .springframework .boot .actuate .endpoint .web .EndpointMapping ;
47
47
import org .springframework .boot .actuate .endpoint .web .ExposableWebEndpoint ;
48
48
import org .springframework .boot .actuate .endpoint .web .WebOperation ;
49
49
import org .springframework .boot .actuate .endpoint .web .WebOperationRequestPredicate ;
74
74
import org .springframework .security .core .userdetails .User ;
75
75
import org .springframework .security .web .server .SecurityWebFilterChain ;
76
76
import org .springframework .security .web .server .WebFilterChainProxy ;
77
- import org .springframework .test .util .ReflectionTestUtils ;
78
77
import org .springframework .test .web .reactive .server .WebTestClient ;
79
78
import org .springframework .web .cors .CorsConfiguration ;
80
79
import org .springframework .web .reactive .function .client .WebClient ;
@@ -121,16 +120,16 @@ void cloudFoundryPlatformActive() {
121
120
"vcap.application.cf_api:https://my-cloud-controller.com" )
122
121
.run ((context ) -> {
123
122
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping (context );
124
- EndpointMapping endpointMapping = ( EndpointMapping ) ReflectionTestUtils . getField ( handlerMapping ,
125
- "endpointMapping" );
126
- assertThat ( endpointMapping . getPath ()). isEqualTo ( "/cloudfoundryapplication" );
127
- CorsConfiguration corsConfiguration = ( CorsConfiguration ) ReflectionTestUtils . getField ( handlerMapping ,
128
- " corsConfiguration" );
129
- assertThat (corsConfiguration .getAllowedOrigins ()). contains ( "*" );
130
- assertThat ( corsConfiguration . getAllowedMethods ())
131
- . containsAll ( Arrays . asList ( HttpMethod . GET . name (), HttpMethod . POST . name ()));
132
- assertThat ( corsConfiguration . getAllowedHeaders ())
133
- . containsAll ( Arrays . asList ( "Authorization" , "X-Cf-App-Instance" , "Content-Type" ) );
123
+ assertThat ( handlerMapping ). extracting ( "endpointMapping.path" ). isEqualTo ( "/cloudfoundryapplication" );
124
+ assertThat ( handlerMapping )
125
+ . extracting ( "corsConfiguration" , InstanceOfAssertFactories . type ( CorsConfiguration . class ))
126
+ . satisfies (( corsConfiguration ) -> {
127
+ assertThat ( corsConfiguration . getAllowedOrigins ()). contains ( "* " );
128
+ assertThat (corsConfiguration .getAllowedMethods ())
129
+ . containsAll ( Arrays . asList ( HttpMethod . GET . name (), HttpMethod . POST . name ()));
130
+ assertThat ( corsConfiguration . getAllowedHeaders ())
131
+ . containsAll ( Arrays . asList ( "Authorization" , "X-Cf-App-Instance" , "Content-Type" ));
132
+ } );
134
133
});
135
134
}
136
135
@@ -150,41 +149,27 @@ void cloudFoundryPlatformActiveSetsApplicationId() {
150
149
this .contextRunner
151
150
.withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" ,
152
151
"vcap.application.cf_api:https://my-cloud-controller.com" )
153
- .run ((context ) -> {
154
- CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping (context );
155
- Object interceptor = ReflectionTestUtils .getField (handlerMapping , "securityInterceptor" );
156
- String applicationId = (String ) ReflectionTestUtils .getField (interceptor , "applicationId" );
157
- assertThat (applicationId ).isEqualTo ("my-app-id" );
158
- });
152
+ .run ((context ) -> assertThat (getHandlerMapping (context )).extracting ("securityInterceptor.applicationId" )
153
+ .isEqualTo ("my-app-id" ));
159
154
}
160
155
161
156
@ Test
162
157
void cloudFoundryPlatformActiveSetsCloudControllerUrl () {
163
158
this .contextRunner
164
159
.withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" ,
165
160
"vcap.application.cf_api:https://my-cloud-controller.com" )
166
- .run ((context ) -> {
167
- CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping (context );
168
- Object interceptor = ReflectionTestUtils .getField (handlerMapping , "securityInterceptor" );
169
- Object interceptorSecurityService = ReflectionTestUtils .getField (interceptor ,
170
- "cloudFoundrySecurityService" );
171
- String cloudControllerUrl = (String ) ReflectionTestUtils .getField (interceptorSecurityService ,
172
- "cloudControllerUrl" );
173
- assertThat (cloudControllerUrl ).isEqualTo ("https://my-cloud-controller.com" );
174
- });
161
+ .run ((context ) -> assertThat (getHandlerMapping (context ))
162
+ .extracting ("securityInterceptor.cloudFoundrySecurityService.cloudControllerUrl" )
163
+ .isEqualTo ("https://my-cloud-controller.com" ));
175
164
}
176
165
177
166
@ Test
178
167
void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent () {
179
168
this .contextRunner .withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" )
180
- .run ((context ) -> {
181
- CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = context .getBean (
182
- "cloudFoundryWebFluxEndpointHandlerMapping" , CloudFoundryWebFluxEndpointHandlerMapping .class );
183
- Object securityInterceptor = ReflectionTestUtils .getField (handlerMapping , "securityInterceptor" );
184
- Object interceptorSecurityService = ReflectionTestUtils .getField (securityInterceptor ,
185
- "cloudFoundrySecurityService" );
186
- assertThat (interceptorSecurityService ).isNull ();
187
- });
169
+ .run ((context ) -> assertThat (context .getBean ("cloudFoundryWebFluxEndpointHandlerMapping" ,
170
+ CloudFoundryWebFluxEndpointHandlerMapping .class ))
171
+ .extracting ("securityInterceptor.cloudFoundrySecurityService" )
172
+ .isNull ());
188
173
}
189
174
190
175
@ Test
@@ -194,30 +179,30 @@ void cloudFoundryPathsIgnoredBySpringSecurity() {
194
179
.withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" ,
195
180
"vcap.application.cf_api:https://my-cloud-controller.com" )
196
181
.run ((context ) -> {
197
- WebFilterChainProxy chainProxy = context .getBean (WebFilterChainProxy .class );
198
- List <SecurityWebFilterChain > filters = (List <SecurityWebFilterChain >) ReflectionTestUtils
199
- .getField (chainProxy , "filters" );
200
- Boolean cfBaseRequestMatches = getMatches (filters , BASE_PATH );
201
- Boolean cfBaseWithTrailingSlashRequestMatches = getMatches (filters , BASE_PATH + "/" );
202
- Boolean cfRequestMatches = getMatches (filters , BASE_PATH + "/test" );
203
- Boolean cfRequestWithAdditionalPathMatches = getMatches (filters , BASE_PATH + "/test/a" );
204
- Boolean otherCfRequestMatches = getMatches (filters , BASE_PATH + "/other-path" );
205
- Boolean otherRequestMatches = getMatches (filters , "/some-other-path" );
206
- assertThat (cfBaseRequestMatches ).isTrue ();
207
- assertThat (cfBaseWithTrailingSlashRequestMatches ).isTrue ();
208
- assertThat (cfRequestMatches ).isTrue ();
209
- assertThat (cfRequestWithAdditionalPathMatches ).isTrue ();
210
- assertThat (otherCfRequestMatches ).isFalse ();
211
- assertThat (otherRequestMatches ).isFalse ();
212
- otherRequestMatches = filters .get (1 )
213
- .matches (MockServerWebExchange .from (MockServerHttpRequest .get ("/some-other-path" ).build ()))
214
- .block (Duration .ofSeconds (30 ));
215
- assertThat (otherRequestMatches ).isTrue ();
182
+ assertThat (context .getBean (WebFilterChainProxy .class ))
183
+ .extracting ("filters" , InstanceOfAssertFactories .list (SecurityWebFilterChain .class ))
184
+ .satisfies ((filters ) -> {
185
+ Boolean cfBaseRequestMatches = getMatches (filters , BASE_PATH );
186
+ Boolean cfBaseWithTrailingSlashRequestMatches = getMatches (filters , BASE_PATH + "/" );
187
+ Boolean cfRequestMatches = getMatches (filters , BASE_PATH + "/test" );
188
+ Boolean cfRequestWithAdditionalPathMatches = getMatches (filters , BASE_PATH + "/test/a" );
189
+ Boolean otherCfRequestMatches = getMatches (filters , BASE_PATH + "/other-path" );
190
+ Boolean otherRequestMatches = getMatches (filters , "/some-other-path" );
191
+ assertThat (cfBaseRequestMatches ).isTrue ();
192
+ assertThat (cfBaseWithTrailingSlashRequestMatches ).isTrue ();
193
+ assertThat (cfRequestMatches ).isTrue ();
194
+ assertThat (cfRequestWithAdditionalPathMatches ).isTrue ();
195
+ assertThat (otherCfRequestMatches ).isFalse ();
196
+ assertThat (otherRequestMatches ).isFalse ();
197
+ otherRequestMatches = filters .get (1 )
198
+ .matches (MockServerWebExchange .from (MockServerHttpRequest .get ("/some-other-path" ).build ()))
199
+ .block (Duration .ofSeconds (30 ));
200
+ assertThat (otherRequestMatches ).isTrue ();
201
+ });
216
202
});
217
-
218
203
}
219
204
220
- private static Boolean getMatches (List <SecurityWebFilterChain > filters , String urlTemplate ) {
205
+ private static Boolean getMatches (List <? extends SecurityWebFilterChain > filters , String urlTemplate ) {
221
206
return filters .get (0 )
222
207
.matches (MockServerWebExchange .from (MockServerHttpRequest .get (urlTemplate ).build ()))
223
208
.block (Duration .ofSeconds (30 ));
@@ -322,20 +307,17 @@ void skipSslValidation() throws IOException {
322
307
.withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" ,
323
308
"vcap.application.cf_api:https://my-cloud-controller.com" ,
324
309
"management.cloudfoundry.skip-ssl-validation:true" )
325
- .run ((context ) -> {
326
- CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping (context );
327
- Object interceptor = ReflectionTestUtils .getField (handlerMapping , "securityInterceptor" );
328
- Object interceptorSecurityService = ReflectionTestUtils .getField (interceptor ,
329
- "cloudFoundrySecurityService" );
330
- WebClient webClient = (WebClient ) ReflectionTestUtils .getField (interceptorSecurityService ,
331
- "webClient" );
332
- ResponseEntity <Void > response = webClient .get ()
333
- .uri (server .url ("/" ).uri ())
334
- .retrieve ()
335
- .toBodilessEntity ()
336
- .block (Duration .ofSeconds (30 ));
337
- assertThat (response .getStatusCode ()).isEqualTo (HttpStatusCode .valueOf (204 ));
338
- });
310
+ .run ((context ) -> assertThat (getHandlerMapping (context ))
311
+ .extracting ("securityInterceptor.cloudFoundrySecurityService.webClient" ,
312
+ InstanceOfAssertFactories .type (WebClient .class ))
313
+ .satisfies ((webClient ) -> {
314
+ ResponseEntity <Void > response = webClient .get ()
315
+ .uri (server .url ("/" ).uri ())
316
+ .retrieve ()
317
+ .toBodilessEntity ()
318
+ .block (Duration .ofSeconds (30 ));
319
+ assertThat (response .getStatusCode ()).isEqualTo (HttpStatusCode .valueOf (204 ));
320
+ }));
339
321
}
340
322
}
341
323
@@ -351,21 +333,16 @@ void sslValidationNotSkippedByDefault() throws IOException {
351
333
this .contextRunner .withConfiguration (AutoConfigurations .of (HealthEndpointAutoConfiguration .class ))
352
334
.withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" ,
353
335
"vcap.application.cf_api:https://my-cloud-controller.com" )
354
- .run ((context ) -> {
355
- CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping (context );
356
- Object interceptor = ReflectionTestUtils .getField (handlerMapping , "securityInterceptor" );
357
- Object interceptorSecurityService = ReflectionTestUtils .getField (interceptor ,
358
- "cloudFoundrySecurityService" );
359
- WebClient webClient = (WebClient ) ReflectionTestUtils .getField (interceptorSecurityService ,
360
- "webClient" );
361
- assertThatExceptionOfType (RuntimeException .class )
336
+ .run ((context ) -> assertThat (getHandlerMapping (context ))
337
+ .extracting ("securityInterceptor.cloudFoundrySecurityService.webClient" ,
338
+ InstanceOfAssertFactories .type (WebClient .class ))
339
+ .satisfies ((webClient ) -> assertThatExceptionOfType (RuntimeException .class )
362
340
.isThrownBy (() -> webClient .get ()
363
341
.uri (server .url ("/" ).uri ())
364
342
.retrieve ()
365
343
.toBodilessEntity ()
366
344
.block (Duration .ofSeconds (30 )))
367
- .withCauseInstanceOf (SSLException .class );
368
- });
345
+ .withCauseInstanceOf (SSLException .class )));
369
346
}
370
347
}
371
348
0 commit comments