52
52
import org .springframework .security .oauth2 .server .resource .authentication .JwtAuthenticationToken ;
53
53
import org .springframework .security .oauth2 .server .resource .web .BearerTokenResolver ;
54
54
import org .springframework .security .web .AuthenticationEntryPoint ;
55
+ import org .springframework .security .web .authentication .AuthenticationConverter ;
55
56
import org .springframework .security .web .authentication .AuthenticationFailureHandler ;
56
57
import org .springframework .security .web .context .RequestAttributeSecurityContextRepository ;
57
58
import org .springframework .security .web .context .SecurityContextRepository ;
74
75
@ ExtendWith (MockitoExtension .class )
75
76
public class BearerTokenAuthenticationFilterTests {
76
77
78
+ private static final String TEST_TOKEN = "token" ;
79
+
77
80
@ Mock
78
81
AuthenticationEntryPoint authenticationEntryPoint ;
79
82
@@ -92,6 +95,9 @@ public class BearerTokenAuthenticationFilterTests {
92
95
@ Mock
93
96
AuthenticationDetailsSource <HttpServletRequest , ?> authenticationDetailsSource ;
94
97
98
+ @ Mock
99
+ AuthenticationConverter authenticationConverter ;
100
+
95
101
MockHttpServletRequest request ;
96
102
97
103
MockHttpServletResponse response ;
@@ -321,6 +327,171 @@ public void constructorWhenNullAuthenticationManagerResolverThenThrowsException(
321
327
// @formatter:on
322
328
}
323
329
330
+ @ Test
331
+ public void doFilterWhenBearerTokenPresentAndConverterSetThenAuthenticates () throws ServletException , IOException {
332
+ given (this .authenticationConverter .convert (this .request ))
333
+ .willReturn (new BearerTokenAuthenticationToken (TEST_TOKEN ));
334
+ BearerTokenAuthenticationFilter filter = addMocksWithConverter (
335
+ new BearerTokenAuthenticationFilter (this .authenticationManager ));
336
+
337
+ filter .doFilter (this .request , this .response , this .filterChain );
338
+
339
+ ArgumentCaptor <BearerTokenAuthenticationToken > captor = ArgumentCaptor
340
+ .forClass (BearerTokenAuthenticationToken .class );
341
+ verify (this .authenticationManager ).authenticate (captor .capture ());
342
+ assertThat (captor .getValue ().getPrincipal ()).isEqualTo (TEST_TOKEN );
343
+ assertThat (this .request .getAttribute (RequestAttributeSecurityContextRepository .DEFAULT_REQUEST_ATTR_NAME ))
344
+ .isNotNull ();
345
+ }
346
+
347
+ @ Test
348
+ public void doFilterWhenSecurityContextRepositoryAndConverterSetThenSaves () throws ServletException , IOException {
349
+ SecurityContextRepository securityContextRepository = mock (SecurityContextRepository .class );
350
+ given (this .authenticationConverter .convert (this .request ))
351
+ .willReturn (new BearerTokenAuthenticationToken (TEST_TOKEN ));
352
+ TestingAuthenticationToken expectedAuthentication = new TestingAuthenticationToken ("test" , "password" );
353
+ given (this .authenticationManager .authenticate (any ())).willReturn (expectedAuthentication );
354
+ BearerTokenAuthenticationFilter filter = addMocksWithConverter (
355
+ new BearerTokenAuthenticationFilter (this .authenticationManager ));
356
+ filter .setSecurityContextRepository (securityContextRepository );
357
+
358
+ filter .doFilter (this .request , this .response , this .filterChain );
359
+
360
+ ArgumentCaptor <BearerTokenAuthenticationToken > captor = ArgumentCaptor
361
+ .forClass (BearerTokenAuthenticationToken .class );
362
+ verify (this .authenticationManager ).authenticate (captor .capture ());
363
+ assertThat (captor .getValue ().getPrincipal ()).isEqualTo (TEST_TOKEN );
364
+ ArgumentCaptor <SecurityContext > contextArg = ArgumentCaptor .forClass (SecurityContext .class );
365
+ verify (securityContextRepository ).saveContext (contextArg .capture (), eq (this .request ), eq (this .response ));
366
+ assertThat (contextArg .getValue ().getAuthentication ().getName ()).isEqualTo (expectedAuthentication .getName ());
367
+ }
368
+
369
+ @ Test
370
+ public void doFilterWhenUsingAuthenticationManagerResolverAndConverterSetThenAuthenticates () throws Exception {
371
+ BearerTokenAuthenticationFilter filter = addMocksWithConverter (
372
+ new BearerTokenAuthenticationFilter (this .authenticationManagerResolver ));
373
+ given (this .authenticationConverter .convert (this .request ))
374
+ .willReturn (new BearerTokenAuthenticationToken (TEST_TOKEN ));
375
+ given (this .authenticationManagerResolver .resolve (any ())).willReturn (this .authenticationManager );
376
+
377
+ filter .doFilter (this .request , this .response , this .filterChain );
378
+
379
+ ArgumentCaptor <BearerTokenAuthenticationToken > captor = ArgumentCaptor
380
+ .forClass (BearerTokenAuthenticationToken .class );
381
+ verify (this .authenticationManager ).authenticate (captor .capture ());
382
+ assertThat (captor .getValue ().getPrincipal ()).isEqualTo (TEST_TOKEN );
383
+ assertThat (this .request .getAttribute (RequestAttributeSecurityContextRepository .DEFAULT_REQUEST_ATTR_NAME ))
384
+ .isNotNull ();
385
+ }
386
+
387
+ @ Test
388
+ public void doFilterWhenNoBearerTokenPresentAndConverterSetThenDoesNotAuthenticate ()
389
+ throws ServletException , IOException {
390
+ given (this .authenticationConverter .convert (this .request )).willReturn (null );
391
+ BearerTokenAuthenticationFilter filter = addMocksWithConverter (
392
+ new BearerTokenAuthenticationFilter (this .authenticationManager ));
393
+
394
+ filter .doFilter (this .request , this .response , this .filterChain );
395
+
396
+ verifyNoMoreInteractions (this .authenticationManager );
397
+ }
398
+
399
+ @ Test
400
+ public void doFilterWhenMalformedBearerTokenAndConverterSetThenPropagatesError ()
401
+ throws ServletException , IOException {
402
+ BearerTokenError error = new BearerTokenError (BearerTokenErrorCodes .INVALID_REQUEST , HttpStatus .BAD_REQUEST ,
403
+ "description" , "uri" );
404
+ OAuth2AuthenticationException exception = new OAuth2AuthenticationException (error );
405
+ given (this .authenticationConverter .convert (this .request )).willThrow (exception );
406
+ BearerTokenAuthenticationFilter filter = addMocksWithConverter (
407
+ new BearerTokenAuthenticationFilter (this .authenticationManager ));
408
+ filter .doFilter (this .request , this .response , this .filterChain );
409
+
410
+ verifyNoMoreInteractions (this .authenticationManager );
411
+ verify (this .authenticationEntryPoint ).commence (this .request , this .response , exception );
412
+ }
413
+
414
+ @ Test
415
+ public void doFilterWhenAuthenticationFailsWithDefaultHandlerAndConverterSetThenPropagatesError ()
416
+ throws ServletException , IOException {
417
+ BearerTokenError error = new BearerTokenError (BearerTokenErrorCodes .INVALID_TOKEN , HttpStatus .UNAUTHORIZED ,
418
+ "description" , "uri" );
419
+ OAuth2AuthenticationException exception = new OAuth2AuthenticationException (error );
420
+ given (this .authenticationConverter .convert (this .request ))
421
+ .willReturn (new BearerTokenAuthenticationToken (TEST_TOKEN ));
422
+ given (this .authenticationManager .authenticate (any (BearerTokenAuthenticationToken .class ))).willThrow (exception );
423
+ BearerTokenAuthenticationFilter filter = addMocksWithConverter (
424
+ new BearerTokenAuthenticationFilter (this .authenticationManager ));
425
+
426
+ filter .doFilter (this .request , this .response , this .filterChain );
427
+
428
+ verify (this .authenticationEntryPoint ).commence (this .request , this .response , exception );
429
+ }
430
+
431
+ @ Test
432
+ public void doFilterWhenAuthenticationFailsWithCustomHandlerAndConverterSetThenPropagatesError ()
433
+ throws ServletException , IOException {
434
+ BearerTokenError error = new BearerTokenError (BearerTokenErrorCodes .INVALID_TOKEN , HttpStatus .UNAUTHORIZED ,
435
+ "description" , "uri" );
436
+ OAuth2AuthenticationException exception = new OAuth2AuthenticationException (error );
437
+ given (this .authenticationConverter .convert (this .request ))
438
+ .willReturn (new BearerTokenAuthenticationToken (TEST_TOKEN ));
439
+ given (this .authenticationManager .authenticate (any (BearerTokenAuthenticationToken .class ))).willThrow (exception );
440
+ BearerTokenAuthenticationFilter filter = addMocksWithConverter (
441
+ new BearerTokenAuthenticationFilter (this .authenticationManager ));
442
+ filter .setAuthenticationFailureHandler (this .authenticationFailureHandler );
443
+
444
+ filter .doFilter (this .request , this .response , this .filterChain );
445
+
446
+ verify (this .authenticationFailureHandler ).onAuthenticationFailure (this .request , this .response , exception );
447
+ }
448
+
449
+ @ Test
450
+ public void doFilterWhenConverterSetAndAuthenticationServiceExceptionThenRethrows () {
451
+ AuthenticationServiceException exception = new AuthenticationServiceException ("message" );
452
+ given (this .authenticationConverter .convert (this .request ))
453
+ .willReturn (new BearerTokenAuthenticationToken (TEST_TOKEN ));
454
+ given (this .authenticationManager .authenticate (any ())).willThrow (exception );
455
+ BearerTokenAuthenticationFilter filter = addMocksWithConverter (
456
+ new BearerTokenAuthenticationFilter (this .authenticationManager ));
457
+
458
+ assertThatExceptionOfType (AuthenticationServiceException .class )
459
+ .isThrownBy (() -> filter .doFilter (this .request , this .response , this .filterChain ));
460
+ }
461
+
462
+ @ Test
463
+ public void doFilterWhenConverterSetAndCustomEntryPointAndAuthenticationErrorThenUses ()
464
+ throws ServletException , IOException {
465
+ AuthenticationException exception = new InvalidBearerTokenException ("message" );
466
+ given (this .authenticationConverter .convert (this .request ))
467
+ .willReturn (new BearerTokenAuthenticationToken (TEST_TOKEN ));
468
+ given (this .authenticationManager .authenticate (any ())).willThrow (exception );
469
+ BearerTokenAuthenticationFilter filter = addMocksWithConverter (
470
+ new BearerTokenAuthenticationFilter (this .authenticationManager ));
471
+ AuthenticationEntryPoint entrypoint = mock (AuthenticationEntryPoint .class );
472
+ filter .setAuthenticationEntryPoint (entrypoint );
473
+
474
+ filter .doFilter (this .request , this .response , this .filterChain );
475
+
476
+ verify (entrypoint ).commence (any (), any (), any (InvalidBearerTokenException .class ));
477
+ }
478
+
479
+ @ Test
480
+ public void doFilterWhenConverterSetCustomSecurityContextHolderStrategyThenUses ()
481
+ throws ServletException , IOException {
482
+ given (this .authenticationConverter .convert (this .request ))
483
+ .willReturn (new BearerTokenAuthenticationToken (TEST_TOKEN ));
484
+ BearerTokenAuthenticationFilter filter = addMocksWithConverter (
485
+ new BearerTokenAuthenticationFilter (this .authenticationManager ));
486
+ SecurityContextHolderStrategy strategy = mock (SecurityContextHolderStrategy .class );
487
+ given (strategy .createEmptyContext ()).willReturn (new SecurityContextImpl ());
488
+ filter .setSecurityContextHolderStrategy (strategy );
489
+
490
+ filter .doFilter (this .request , this .response , this .filterChain );
491
+
492
+ verify (strategy ).setContext (any ());
493
+ }
494
+
324
495
private BearerTokenAuthenticationFilter addMocks (BearerTokenAuthenticationFilter filter ) {
325
496
filter .setAuthenticationEntryPoint (this .authenticationEntryPoint );
326
497
filter .setBearerTokenResolver (this .bearerTokenResolver );
@@ -335,4 +506,10 @@ private void dontAuthenticate() throws ServletException, IOException {
335
506
verifyNoMoreInteractions (this .authenticationManager );
336
507
}
337
508
509
+ private BearerTokenAuthenticationFilter addMocksWithConverter (BearerTokenAuthenticationFilter filter ) {
510
+ filter .setAuthenticationEntryPoint (this .authenticationEntryPoint );
511
+ filter .setAuthenticationConverter (this .authenticationConverter );
512
+ return filter ;
513
+ }
514
+
338
515
}
0 commit comments