diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurer.java index 62bb660bbd..3b0b19fdc1 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurer.java @@ -39,7 +39,6 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; -import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider; import org.springframework.security.oauth2.server.resource.authentication.OpaqueTokenAuthenticationProvider; @@ -52,7 +51,6 @@ import org.springframework.security.oauth2.server.resource.web.DefaultBearerToke import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.access.AccessDeniedHandler; -import org.springframework.security.web.authentication.AuthenticationConverter; import org.springframework.security.web.util.matcher.AndRequestMatcher; import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; import org.springframework.security.web.util.matcher.NegatedRequestMatcher; @@ -80,8 +78,6 @@ import org.springframework.web.accept.HeaderContentNegotiationStrategy; * authentication failures are handled *
  • {@link #bearerTokenResolver(BearerTokenResolver)} - customizes how to resolve a * bearer token from the request
  • - *
  • {@link #authenticationConverter(AuthenticationConverter)}
  • - customizes how to - * convert a bearer token authentication from the request *
  • {@link #jwt(Customizer)} - enables Jwt-encoded bearer token support
  • *
  • {@link #opaqueToken(Customizer)} - enables opaque bearer token support
  • * @@ -163,8 +159,6 @@ public final class OAuth2ResourceServerConfigurer authenticationConverter(AuthenticationConverter authenticationConverter) { - Assert.notNull(authenticationConverter, "authenticationConverter cannot be null"); - this.authenticationConverter = authenticationConverter; - return this; - } - public JwtConfigurer jwt() { if (this.jwtConfigurer == null) { this.jwtConfigurer = new JwtConfigurer(this.context); @@ -265,10 +253,8 @@ public final class OAuth2ResourceServerConfigurer authenticationManager; } - this.authenticationConverter = getAuthenticationConverter(); - BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter(resolver); - filter.setAuthenticationConverter(this.authenticationConverter); + filter.setBearerTokenResolver(bearerTokenResolver); filter.setAuthenticationEntryPoint(this.authenticationEntryPoint); filter = postProcess(filter); http.addFilter(filter); @@ -362,20 +348,6 @@ public final class OAuth2ResourceServerConfigurer 0) { - this.authenticationConverter = this.context.getBean(BearerTokenAuthenticationConverter.class); - } - else { - BearerTokenAuthenticationConverter converter = new BearerTokenAuthenticationConverter(); - converter.setBearerTokenResolver(getBearerTokenResolver()); - this.authenticationConverter = converter; - } - } - return this.authenticationConverter; - } - public class JwtConfigurer { private final ApplicationContext context; diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java index d19091d64e..6a4d40e789 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java @@ -75,11 +75,13 @@ import org.springframework.http.ResponseEntity; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationEventPublisher; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManagerResolver; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.config.annotation.ObjectPostProcessor; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.HttpSecurityBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -109,20 +111,20 @@ import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.JwtTimestampValidator; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.oauth2.jwt.TestJwts; -import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; -import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.JwtIssuerAuthenticationManagerResolver; import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector; import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector; import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; +import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter; import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver; import org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver; import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.access.AccessDeniedHandlerImpl; import org.springframework.test.web.servlet.MockMvc; @@ -724,68 +726,14 @@ public class OAuth2ResourceServerConfigurerTests { } @Test - public void getBearerTokenAuthenticationConverterWhenDuplicateConverterBeansAndAnotherOnTheDslThenTheDslOneIsUsed() { - BearerTokenAuthenticationConverter converterBean = new BearerTokenAuthenticationConverter(); - BearerTokenAuthenticationConverter converter = new BearerTokenAuthenticationConverter(); - GenericWebApplicationContext context = new GenericWebApplicationContext(); - context.registerBean("converterOne", BearerTokenAuthenticationConverter.class, () -> converterBean); - context.registerBean("converterTwo", BearerTokenAuthenticationConverter.class, () -> converterBean); - this.spring.context(context).autowire(); - OAuth2ResourceServerConfigurer oauth2 = new OAuth2ResourceServerConfigurer(context); - oauth2.authenticationConverter(converter); - assertThat(oauth2.getAuthenticationConverter()).isEqualTo(converter); - } - - @Test - public void getBearerTokenAuthenticationConverterWhenDuplicateConverterBeansThenWiringException() { - assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> this.spring - .register(MultipleBearerTokenAuthenticationConverterBeansConfig.class, JwtDecoderConfig.class) - .autowire()).withRootCauseInstanceOf(NoUniqueBeanDefinitionException.class); - } - - @Test - public void getBearerTokenAuthenticationConverterWhenConverterBeanAndAnotherOnTheDslThenTheDslOneIsUsed() { - BearerTokenAuthenticationConverter converter = new BearerTokenAuthenticationConverter(); - BearerTokenAuthenticationConverter converterBean = new BearerTokenAuthenticationConverter(); - GenericWebApplicationContext context = new GenericWebApplicationContext(); - context.registerBean(BearerTokenAuthenticationConverter.class, () -> converterBean); - this.spring.context(context).autowire(); - OAuth2ResourceServerConfigurer oauth2 = new OAuth2ResourceServerConfigurer(context); - oauth2.authenticationConverter(converter); - assertThat(oauth2.getAuthenticationConverter()).isEqualTo(converter); - } - - @Test - public void getBearerTokenAuthenticationConverterWhenNoConverterSpecifiedThenTheDefaultIsUsed() { - ApplicationContext context = this.spring.context(new GenericWebApplicationContext()).getContext(); - OAuth2ResourceServerConfigurer oauth2 = new OAuth2ResourceServerConfigurer(context); - assertThat(oauth2.getAuthenticationConverter()).isInstanceOf(BearerTokenAuthenticationConverter.class); - } - - @Test - public void getBearerTokenAuthenticationConverterWhenConverterBeanRegisteredThenBeanIsUsed() { - BearerTokenAuthenticationConverter converterBean = new BearerTokenAuthenticationConverter(); - GenericWebApplicationContext context = new GenericWebApplicationContext(); - context.registerBean(BearerTokenAuthenticationConverter.class, () -> converterBean); - this.spring.context(context).autowire(); - OAuth2ResourceServerConfigurer oauth2 = new OAuth2ResourceServerConfigurer(context); - assertThat(oauth2.getAuthenticationConverter()).isEqualTo(converterBean); - - } - - @Test - public void getBearerTokenAuthenticationConverterWhenOnlyResolverBeanRegisteredThenUseTheResolver() { - HttpServletRequest servletRequest = mock(HttpServletRequest.class); - BearerTokenResolver resolverBean = (request) -> "bearer customToken"; - GenericWebApplicationContext context = new GenericWebApplicationContext(); - context.registerBean(BearerTokenResolver.class, () -> resolverBean); - this.spring.context(context).autowire(); - OAuth2ResourceServerConfigurer oauth2 = new OAuth2ResourceServerConfigurer(context); - BearerTokenAuthenticationToken bearerTokenAuthenticationToken = (BearerTokenAuthenticationToken) oauth2 - .getAuthenticationConverter().convert(servletRequest); - String token = bearerTokenAuthenticationToken.getToken(); - assertThat(token).isEqualTo("bearer customToken"); - + public void requestWhenCustomAuthenticationDetailsSourceThenUsed() throws Exception { + this.spring.register(CustomAuthenticationDetailsSource.class, JwtDecoderConfig.class, BasicController.class) + .autowire(); + JwtDecoder decoder = this.spring.getContext().getBean(JwtDecoder.class); + given(decoder.decode(anyString())).willReturn(JWT); + this.mvc.perform(get("/authenticated").with(bearerToken(JWT_TOKEN))).andExpect(status().isOk()) + .andExpect(content().string(JWT_SUBJECT)); + verifyBean(AuthenticationDetailsSource.class).buildDetails(any()); } @Test @@ -1940,29 +1888,35 @@ public class OAuth2ResourceServerConfigurerTests { } @EnableWebSecurity - static class MultipleBearerTokenAuthenticationConverterBeansConfig extends WebSecurityConfigurerAdapter { + static class CustomAuthenticationDetailsSource { - @Override - protected void configure(HttpSecurity http) throws Exception { + AuthenticationDetailsSource authenticationDetailsSource = mock( + AuthenticationDetailsSource.class); + + @Bean + SecurityFilterChain web(HttpSecurity http) throws Exception { // @formatter:off http - .oauth2ResourceServer() - .jwt(); - // @formatter:on + .authorizeRequests((authorize) -> authorize + .anyRequest().authenticated() + ) + .oauth2ResourceServer((oauth2) -> oauth2 + .jwt(withDefaults()) + .withObjectPostProcessor(new ObjectPostProcessor() { + @Override + public BearerTokenAuthenticationFilter postProcess(BearerTokenAuthenticationFilter object) { + object.setAuthenticationDetailsSource(CustomAuthenticationDetailsSource.this.authenticationDetailsSource); + return object; + } + }) + ); + return http.build(); } @Bean - BearerTokenAuthenticationConverter converterOne() { - BearerTokenAuthenticationConverter converter = new BearerTokenAuthenticationConverter(); - return converter; + AuthenticationDetailsSource authenticationDetailsSource() { + return this.authenticationDetailsSource; } - - @Bean - BearerTokenAuthenticationConverter converterTwo() { - BearerTokenAuthenticationConverter converter = new BearerTokenAuthenticationConverter(); - return converter; - } - } @EnableWebSecurity diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationConverter.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationConverter.java deleted file mode 100644 index 389fdb8f9b..0000000000 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationConverter.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.security.oauth2.server.resource.authentication; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.security.authentication.AuthenticationDetailsSource; -import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; -import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver; -import org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver; -import org.springframework.security.web.authentication.AuthenticationConverter; -import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; -import org.springframework.util.Assert; - -/** - * Converts from a HttpServletRequest to {@link BearerTokenAuthenticationToken} that can - * be authenticated. Null authentication possible if there was no Authorization header - * with Bearer Token. - * - * @author Jeongjin Kim - * @since 5.5 - */ -public final class BearerTokenAuthenticationConverter implements AuthenticationConverter { - - private BearerTokenResolver bearerTokenResolver = new DefaultBearerTokenResolver(); - - private AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource(); - - @Override - public BearerTokenAuthenticationToken convert(HttpServletRequest request) { - String token = this.bearerTokenResolver.resolve(request); - - if (token == null) { - return null; - } - - BearerTokenAuthenticationToken authenticationRequest = new BearerTokenAuthenticationToken(token); - authenticationRequest.setDetails(this.authenticationDetailsSource.buildDetails(request)); - return authenticationRequest; - } - - /** - * Set the {@link BearerTokenResolver} to use. Defaults to - * {@link DefaultBearerTokenResolver}. - * @param bearerTokenResolver the {@code BearerTokenResolver} to use - */ - public void setBearerTokenResolver(BearerTokenResolver bearerTokenResolver) { - Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null"); - this.bearerTokenResolver = bearerTokenResolver; - } - - /** - * Set the {@link AuthenticationDetailsSource} to use. Defaults to - * {@link WebAuthenticationDetailsSource}. - * @param authenticationDetailsSource the {@code AuthenticationDetailsSource} to use - */ - public void setAuthenticationDetailsSource( - AuthenticationDetailsSource authenticationDetailsSource) { - Assert.notNull(authenticationDetailsSource, "authenticationDetailsSource cannot be null"); - this.authenticationDetailsSource = authenticationDetailsSource; - } - -} diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilter.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilter.java index 3c709f40e7..ffa9701ad3 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilter.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilter.java @@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.core.log.LogMessage; +import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManagerResolver; import org.springframework.security.authentication.AuthenticationServiceException; @@ -31,12 +32,12 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; -import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider; 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.authentication.WebAuthenticationDetailsSource; import org.springframework.util.Assert; import org.springframework.web.filter.OncePerRequestFilter; @@ -51,6 +52,7 @@ import org.springframework.web.filter.OncePerRequestFilter; * @author Josh Cummings * @author Vedran Pavic * @author Joe Grandja + * @author Jeongjin Kim * @since 5.1 * @see The OAuth 2.0 * Authorization Framework: Bearer Token Usage @@ -69,7 +71,9 @@ public final class BearerTokenAuthenticationFilter extends OncePerRequestFilter this.authenticationEntryPoint.commence(request, response, exception); }; - private AuthenticationConverter authenticationConverter = new BearerTokenAuthenticationConverter(); + private BearerTokenResolver bearerTokenResolver = new DefaultBearerTokenResolver(); + + private AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource(); /** * Construct a {@code BearerTokenAuthenticationFilter} using the provided parameter(s) @@ -103,21 +107,24 @@ public final class BearerTokenAuthenticationFilter extends OncePerRequestFilter @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - Authentication authenticationRequest; + String token; try { - authenticationRequest = this.authenticationConverter.convert(request); + token = this.bearerTokenResolver.resolve(request); } - catch (AuthenticationException invalid) { + catch (OAuth2AuthenticationException invalid) { this.logger.trace("Sending to authentication entry point since failed to resolve bearer token", invalid); this.authenticationEntryPoint.commence(request, response, invalid); return; } - if (authenticationRequest == null) { + if (token == null) { this.logger.trace("Did not process request since did not find bearer token"); filterChain.doFilter(request, response); return; } + BearerTokenAuthenticationToken authenticationRequest = new BearerTokenAuthenticationToken(token); + authenticationRequest.setDetails(this.authenticationDetailsSource.buildDetails(request)); + try { AuthenticationManager authenticationManager = this.authenticationManagerResolver.resolve(request); Authentication authenticationResult = authenticationManager.authenticate(authenticationRequest); @@ -140,28 +147,10 @@ public final class BearerTokenAuthenticationFilter extends OncePerRequestFilter * Set the {@link BearerTokenResolver} to use. Defaults to * {@link DefaultBearerTokenResolver}. * @param bearerTokenResolver the {@code BearerTokenResolver} to use - * @deprecated Instead, use {@link BearerTokenAuthenticationConverter} explicitly - * @see BearerTokenAuthenticationConverter */ - @Deprecated public void setBearerTokenResolver(BearerTokenResolver bearerTokenResolver) { Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null"); - Assert.isTrue(this.authenticationConverter instanceof BearerTokenAuthenticationConverter, - "bearerTokenResolver and authenticationConverter cannot both be customized in this filter. " - + "Since you've customized the authenticationConverter, " - + "please consider configuring the bearerTokenResolver there."); - ((BearerTokenAuthenticationConverter) this.authenticationConverter).setBearerTokenResolver(bearerTokenResolver); - } - - /** - * Set the {@link AuthenticationConverter} to use. Defaults to - * {@link BearerTokenAuthenticationConverter}. - * @param authenticationConverter the {@code AuthenticationConverter} to use - * @since 5.5 - */ - public void setAuthenticationConverter(AuthenticationConverter authenticationConverter) { - Assert.notNull(authenticationConverter, "authenticationConverter cannot be null"); - this.authenticationConverter = authenticationConverter; + this.bearerTokenResolver = bearerTokenResolver; } /** @@ -185,4 +174,16 @@ public final class BearerTokenAuthenticationFilter extends OncePerRequestFilter this.authenticationFailureHandler = authenticationFailureHandler; } + /** + * Set the {@link AuthenticationDetailsSource} to use. Defaults to + * {@link WebAuthenticationDetailsSource}. + * @param authenticationDetailsSource the {@code AuthenticationConverter} to use + * @since 5.5 + */ + public void setAuthenticationDetailsSource( + AuthenticationDetailsSource authenticationDetailsSource) { + Assert.notNull(authenticationDetailsSource, "authenticationDetailsSource cannot be null"); + this.authenticationDetailsSource = authenticationDetailsSource; + } + } diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationConverterTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationConverterTests.java deleted file mode 100644 index 8f46a381dd..0000000000 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationConverterTests.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.security.oauth2.server.resource.authentication; - -import javax.servlet.http.HttpServletRequest; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.http.HttpHeaders; -import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link BearerTokenAuthenticationConverter} - * - * @author Jeongjin Kim - * @since 5.5 - */ -@RunWith(MockitoJUnitRunner.class) -public class BearerTokenAuthenticationConverterTests { - - private BearerTokenAuthenticationConverter converter; - - @Before - public void setup() { - this.converter = new BearerTokenAuthenticationConverter(); - } - - @Test - public void setBearerTokenResolverWithNullThenThrowsException() { - // @formatter:off - assertThatIllegalArgumentException() - .isThrownBy(() -> this.converter.setBearerTokenResolver(null)) - .withMessageContaining("bearerTokenResolver cannot be null"); - // @formatter:on - } - - @Test - public void setAuthenticationDetailsSourceWithNullThenThrowsException() { - // @formatter:off - assertThatIllegalArgumentException() - .isThrownBy(() -> this.converter.setAuthenticationDetailsSource(null)) - .withMessageContaining("authenticationDetailsSource cannot be null"); - // @formatter:on - } - - @Test - public void convertWhenNoBearerTokenHeaderThenNull() { - HttpServletRequest request = mock(HttpServletRequest.class); - - BearerTokenAuthenticationToken convert = this.converter.convert(request); - - assertThat(convert).isNull(); - } - - @Test - public void convertWhenBearerTokenThenBearerTokenAuthenticationToken() { - HttpServletRequest request = mock(HttpServletRequest.class); - given(request.getHeader(HttpHeaders.AUTHORIZATION)).willReturn("Bearer token"); - - BearerTokenAuthenticationToken token = this.converter.convert(request); - - assertThat(token.getToken()).isEqualTo("token"); - } - -} diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilterTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilterTests.java index af4b350370..738b13efba 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilterTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilterTests.java @@ -32,6 +32,7 @@ import org.springframework.http.HttpStatus; import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManagerResolver; import org.springframework.security.authentication.AuthenticationServiceException; @@ -73,6 +74,9 @@ public class BearerTokenAuthenticationFilterTests { @Mock BearerTokenResolver bearerTokenResolver; + @Mock + AuthenticationDetailsSource authenticationDetailsSource; + MockHttpServletRequest request; MockHttpServletResponse response; @@ -167,6 +171,15 @@ public class BearerTokenAuthenticationFilterTests { .isThrownBy(() -> filter.doFilter(this.request, this.response, this.filterChain)); } + @Test + public void doFilterWhenCustomAuthenticationDetailsSourceThenUses() throws ServletException, IOException { + given(this.bearerTokenResolver.resolve(this.request)).willReturn("token"); + BearerTokenAuthenticationFilter filter = addMocks( + new BearerTokenAuthenticationFilter(this.authenticationManager)); + filter.doFilter(this.request, this.response, this.filterChain); + verify(this.authenticationDetailsSource).buildDetails(this.request); + } + @Test public void setAuthenticationEntryPointWhenNullThenThrowsException() { BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter(this.authenticationManager); @@ -192,8 +205,8 @@ public class BearerTokenAuthenticationFilterTests { // @formatter:off BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter(this.authenticationManager); assertThatIllegalArgumentException() - .isThrownBy(() -> filter.setAuthenticationConverter(null)) - .withMessageContaining("authenticationConverter cannot be null"); + .isThrownBy(() -> filter.setAuthenticationDetailsSource(null)) + .withMessageContaining("authenticationDetailsSource cannot be null"); // @formatter:on } @@ -218,6 +231,7 @@ public class BearerTokenAuthenticationFilterTests { private BearerTokenAuthenticationFilter addMocks(BearerTokenAuthenticationFilter filter) { filter.setAuthenticationEntryPoint(this.authenticationEntryPoint); filter.setBearerTokenResolver(this.bearerTokenResolver); + filter.setAuthenticationDetailsSource(this.authenticationDetailsSource); return filter; }