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