Add Additional Tests To BearerTokenAuthenticationFilterTests

Issue gh-14750

Signed-off-by: Max Batischev <mblancer@mail.ru>
This commit is contained in:
Max Batischev 2025-04-11 15:36:23 +03:00 committed by Josh Cummings
parent 4967f3feee
commit 30577bd291

View File

@ -52,6 +52,7 @@ import org.springframework.security.oauth2.server.resource.authentication.Bearer
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
@ -74,6 +75,8 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
@ExtendWith(MockitoExtension.class)
public class BearerTokenAuthenticationFilterTests {
private static final String TEST_TOKEN = "token";
@Mock
AuthenticationEntryPoint authenticationEntryPoint;
@ -92,6 +95,9 @@ public class BearerTokenAuthenticationFilterTests {
@Mock
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource;
@Mock
AuthenticationConverter authenticationConverter;
MockHttpServletRequest request;
MockHttpServletResponse response;
@ -321,6 +327,171 @@ public class BearerTokenAuthenticationFilterTests {
// @formatter:on
}
@Test
public void doFilterWhenBearerTokenPresentAndConverterSetThenAuthenticates() throws ServletException, IOException {
given(this.authenticationConverter.convert(this.request))
.willReturn(new BearerTokenAuthenticationToken(TEST_TOKEN));
BearerTokenAuthenticationFilter filter = addMocksWithConverter(
new BearerTokenAuthenticationFilter(this.authenticationManager));
filter.doFilter(this.request, this.response, this.filterChain);
ArgumentCaptor<BearerTokenAuthenticationToken> captor = ArgumentCaptor
.forClass(BearerTokenAuthenticationToken.class);
verify(this.authenticationManager).authenticate(captor.capture());
assertThat(captor.getValue().getPrincipal()).isEqualTo(TEST_TOKEN);
assertThat(this.request.getAttribute(RequestAttributeSecurityContextRepository.DEFAULT_REQUEST_ATTR_NAME))
.isNotNull();
}
@Test
public void doFilterWhenSecurityContextRepositoryAndConverterSetThenSaves() throws ServletException, IOException {
SecurityContextRepository securityContextRepository = mock(SecurityContextRepository.class);
given(this.authenticationConverter.convert(this.request))
.willReturn(new BearerTokenAuthenticationToken(TEST_TOKEN));
TestingAuthenticationToken expectedAuthentication = new TestingAuthenticationToken("test", "password");
given(this.authenticationManager.authenticate(any())).willReturn(expectedAuthentication);
BearerTokenAuthenticationFilter filter = addMocksWithConverter(
new BearerTokenAuthenticationFilter(this.authenticationManager));
filter.setSecurityContextRepository(securityContextRepository);
filter.doFilter(this.request, this.response, this.filterChain);
ArgumentCaptor<BearerTokenAuthenticationToken> captor = ArgumentCaptor
.forClass(BearerTokenAuthenticationToken.class);
verify(this.authenticationManager).authenticate(captor.capture());
assertThat(captor.getValue().getPrincipal()).isEqualTo(TEST_TOKEN);
ArgumentCaptor<SecurityContext> contextArg = ArgumentCaptor.forClass(SecurityContext.class);
verify(securityContextRepository).saveContext(contextArg.capture(), eq(this.request), eq(this.response));
assertThat(contextArg.getValue().getAuthentication().getName()).isEqualTo(expectedAuthentication.getName());
}
@Test
public void doFilterWhenUsingAuthenticationManagerResolverAndConverterSetThenAuthenticates() throws Exception {
BearerTokenAuthenticationFilter filter = addMocksWithConverter(
new BearerTokenAuthenticationFilter(this.authenticationManagerResolver));
given(this.authenticationConverter.convert(this.request))
.willReturn(new BearerTokenAuthenticationToken(TEST_TOKEN));
given(this.authenticationManagerResolver.resolve(any())).willReturn(this.authenticationManager);
filter.doFilter(this.request, this.response, this.filterChain);
ArgumentCaptor<BearerTokenAuthenticationToken> captor = ArgumentCaptor
.forClass(BearerTokenAuthenticationToken.class);
verify(this.authenticationManager).authenticate(captor.capture());
assertThat(captor.getValue().getPrincipal()).isEqualTo(TEST_TOKEN);
assertThat(this.request.getAttribute(RequestAttributeSecurityContextRepository.DEFAULT_REQUEST_ATTR_NAME))
.isNotNull();
}
@Test
public void doFilterWhenNoBearerTokenPresentAndConverterSetThenDoesNotAuthenticate()
throws ServletException, IOException {
given(this.authenticationConverter.convert(this.request)).willReturn(null);
BearerTokenAuthenticationFilter filter = addMocksWithConverter(
new BearerTokenAuthenticationFilter(this.authenticationManager));
filter.doFilter(this.request, this.response, this.filterChain);
verifyNoMoreInteractions(this.authenticationManager);
}
@Test
public void doFilterWhenMalformedBearerTokenAndConverterSetThenPropagatesError()
throws ServletException, IOException {
BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_REQUEST, HttpStatus.BAD_REQUEST,
"description", "uri");
OAuth2AuthenticationException exception = new OAuth2AuthenticationException(error);
given(this.authenticationConverter.convert(this.request)).willThrow(exception);
BearerTokenAuthenticationFilter filter = addMocksWithConverter(
new BearerTokenAuthenticationFilter(this.authenticationManager));
filter.doFilter(this.request, this.response, this.filterChain);
verifyNoMoreInteractions(this.authenticationManager);
verify(this.authenticationEntryPoint).commence(this.request, this.response, exception);
}
@Test
public void doFilterWhenAuthenticationFailsWithDefaultHandlerAndConverterSetThenPropagatesError()
throws ServletException, IOException {
BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_TOKEN, HttpStatus.UNAUTHORIZED,
"description", "uri");
OAuth2AuthenticationException exception = new OAuth2AuthenticationException(error);
given(this.authenticationConverter.convert(this.request))
.willReturn(new BearerTokenAuthenticationToken(TEST_TOKEN));
given(this.authenticationManager.authenticate(any(BearerTokenAuthenticationToken.class))).willThrow(exception);
BearerTokenAuthenticationFilter filter = addMocksWithConverter(
new BearerTokenAuthenticationFilter(this.authenticationManager));
filter.doFilter(this.request, this.response, this.filterChain);
verify(this.authenticationEntryPoint).commence(this.request, this.response, exception);
}
@Test
public void doFilterWhenAuthenticationFailsWithCustomHandlerAndConverterSetThenPropagatesError()
throws ServletException, IOException {
BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_TOKEN, HttpStatus.UNAUTHORIZED,
"description", "uri");
OAuth2AuthenticationException exception = new OAuth2AuthenticationException(error);
given(this.authenticationConverter.convert(this.request))
.willReturn(new BearerTokenAuthenticationToken(TEST_TOKEN));
given(this.authenticationManager.authenticate(any(BearerTokenAuthenticationToken.class))).willThrow(exception);
BearerTokenAuthenticationFilter filter = addMocksWithConverter(
new BearerTokenAuthenticationFilter(this.authenticationManager));
filter.setAuthenticationFailureHandler(this.authenticationFailureHandler);
filter.doFilter(this.request, this.response, this.filterChain);
verify(this.authenticationFailureHandler).onAuthenticationFailure(this.request, this.response, exception);
}
@Test
public void doFilterWhenConverterSetAndAuthenticationServiceExceptionThenRethrows() {
AuthenticationServiceException exception = new AuthenticationServiceException("message");
given(this.authenticationConverter.convert(this.request))
.willReturn(new BearerTokenAuthenticationToken(TEST_TOKEN));
given(this.authenticationManager.authenticate(any())).willThrow(exception);
BearerTokenAuthenticationFilter filter = addMocksWithConverter(
new BearerTokenAuthenticationFilter(this.authenticationManager));
assertThatExceptionOfType(AuthenticationServiceException.class)
.isThrownBy(() -> filter.doFilter(this.request, this.response, this.filterChain));
}
@Test
public void doFilterWhenConverterSetAndCustomEntryPointAndAuthenticationErrorThenUses()
throws ServletException, IOException {
AuthenticationException exception = new InvalidBearerTokenException("message");
given(this.authenticationConverter.convert(this.request))
.willReturn(new BearerTokenAuthenticationToken(TEST_TOKEN));
given(this.authenticationManager.authenticate(any())).willThrow(exception);
BearerTokenAuthenticationFilter filter = addMocksWithConverter(
new BearerTokenAuthenticationFilter(this.authenticationManager));
AuthenticationEntryPoint entrypoint = mock(AuthenticationEntryPoint.class);
filter.setAuthenticationEntryPoint(entrypoint);
filter.doFilter(this.request, this.response, this.filterChain);
verify(entrypoint).commence(any(), any(), any(InvalidBearerTokenException.class));
}
@Test
public void doFilterWhenConverterSetCustomSecurityContextHolderStrategyThenUses()
throws ServletException, IOException {
given(this.authenticationConverter.convert(this.request))
.willReturn(new BearerTokenAuthenticationToken(TEST_TOKEN));
BearerTokenAuthenticationFilter filter = addMocksWithConverter(
new BearerTokenAuthenticationFilter(this.authenticationManager));
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
given(strategy.createEmptyContext()).willReturn(new SecurityContextImpl());
filter.setSecurityContextHolderStrategy(strategy);
filter.doFilter(this.request, this.response, this.filterChain);
verify(strategy).setContext(any());
}
private BearerTokenAuthenticationFilter addMocks(BearerTokenAuthenticationFilter filter) {
filter.setAuthenticationEntryPoint(this.authenticationEntryPoint);
filter.setBearerTokenResolver(this.bearerTokenResolver);
@ -335,4 +506,10 @@ public class BearerTokenAuthenticationFilterTests {
verifyNoMoreInteractions(this.authenticationManager);
}
private BearerTokenAuthenticationFilter addMocksWithConverter(BearerTokenAuthenticationFilter filter) {
filter.setAuthenticationEntryPoint(this.authenticationEntryPoint);
filter.setAuthenticationConverter(this.authenticationConverter);
return filter;
}
}