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 c27a779ea39..271175ad2e5 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * 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.
@@ -39,6 +39,7 @@
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;
@@ -51,6 +52,7 @@
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;
@@ -78,6 +80,8 @@
* authentication failures are handled
*
{@link #bearerTokenResolver(BearerTokenResolver)} - customizes how to resolve a
* bearer token from the request
+ * {@link #bearerTokenAuthenticationConverter(AuthenticationConverter)} -
+ * customizes how to convert a bear token authentication from the request
* {@link #jwt(Customizer)} - enables Jwt-encoded bearer token support
* {@link #opaqueToken(Customizer)} - enables opaque bearer token support
*
@@ -159,6 +163,8 @@ public final class OAuth2ResourceServerConfigurer bearerTokenResolver(BearerTokenResolver
return this;
}
+ public OAuth2ResourceServerConfigurer bearerTokenAuthenticationConverter(
+ 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);
@@ -252,8 +265,11 @@ public void configure(H http) {
AuthenticationManager authenticationManager = getAuthenticationManager(http);
resolver = (request) -> authenticationManager;
}
+
+ this.authenticationConverter = getBearerTokenAuthenticationConverter();
+
BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter(resolver);
- filter.setBearerTokenResolver(bearerTokenResolver);
+ filter.setAuthenticationConverter(this.authenticationConverter);
filter.setAuthenticationEntryPoint(this.authenticationEntryPoint);
filter = postProcess(filter);
http.addFilter(filter);
@@ -347,6 +363,20 @@ BearerTokenResolver getBearerTokenResolver() {
return this.bearerTokenResolver;
}
+ AuthenticationConverter getBearerTokenAuthenticationConverter() {
+ if (this.authenticationConverter == null) {
+ if (this.context.getBeanNamesForType(BearerTokenAuthenticationConverter.class).length > 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 e7c7de2cd85..5072e6d768e 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
@@ -33,6 +33,7 @@
import java.util.stream.Collectors;
import javax.annotation.PreDestroy;
+import javax.servlet.http.HttpServletRequest;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
@@ -108,7 +109,9 @@
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;
@@ -720,6 +723,72 @@ public void getBearerTokenResolverWhenNoResolverSpecifiedThenTheDefaultIsUsed()
assertThat(oauth2.getBearerTokenResolver()).isInstanceOf(DefaultBearerTokenResolver.class);
}
+ @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.bearerTokenAuthenticationConverter(converter);
+ assertThat(oauth2.getBearerTokenAuthenticationConverter()).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.bearerTokenAuthenticationConverter(converter);
+ assertThat(oauth2.getBearerTokenAuthenticationConverter()).isEqualTo(converter);
+ }
+
+ @Test
+ public void getBearerTokenAuthenticationConverterWhenNoConverterSpecifiedThenTheDefaultIsUsed() {
+ ApplicationContext context = this.spring.context(new GenericWebApplicationContext()).getContext();
+ OAuth2ResourceServerConfigurer oauth2 = new OAuth2ResourceServerConfigurer(context);
+ assertThat(oauth2.getBearerTokenAuthenticationConverter())
+ .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.getBearerTokenAuthenticationConverter()).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
+ .getBearerTokenAuthenticationConverter().convert(servletRequest);
+ String token = bearerTokenAuthenticationToken.getToken();
+ assertThat(token).isEqualTo("bearer customToken");
+
+ }
+
@Test
public void requestWhenCustomJwtDecoderWiredOnDslThenUsed() throws Exception {
this.spring.register(CustomJwtDecoderOnDsl.class, BasicController.class).autowire();
@@ -1871,6 +1940,32 @@ BearerTokenResolver resolverTwo() {
}
+ @EnableWebSecurity
+ static class MultipleBearerTokenAuthenticationConverterBeansConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ // @formatter:off
+ http
+ .oauth2ResourceServer()
+ .jwt();
+ // @formatter:on
+ }
+
+ @Bean
+ BearerTokenAuthenticationConverter converterOne() {
+ BearerTokenAuthenticationConverter converter = new BearerTokenAuthenticationConverter();
+ return converter;
+ }
+
+ @Bean
+ BearerTokenAuthenticationConverter converterTwo() {
+ BearerTokenAuthenticationConverter converter = new BearerTokenAuthenticationConverter();
+ return converter;
+ }
+
+ }
+
@EnableWebSecurity
static class CustomJwtDecoderOnDsl extends WebSecurityConfigurerAdapter {
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
new file mode 100644
index 00000000000..a10ffd1c3db
--- /dev/null
+++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationConverter.java
@@ -0,0 +1,81 @@
+/*
+ * 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 AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
+
+ private BearerTokenResolver bearerTokenResolver;
+
+ public BearerTokenAuthenticationConverter() {
+ this.bearerTokenResolver = new DefaultBearerTokenResolver();
+ }
+
+ @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 551101d0ef3..a945cc479a1 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,7 +24,6 @@
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;
@@ -32,12 +31,12 @@
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;
@@ -61,10 +60,6 @@ public final class BearerTokenAuthenticationFilter extends OncePerRequestFilter
private final AuthenticationManagerResolver authenticationManagerResolver;
- private final AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
-
- private BearerTokenResolver bearerTokenResolver = new DefaultBearerTokenResolver();
-
private AuthenticationEntryPoint authenticationEntryPoint = new BearerTokenAuthenticationEntryPoint();
private AuthenticationFailureHandler authenticationFailureHandler = (request, response, exception) -> {
@@ -74,6 +69,8 @@ public final class BearerTokenAuthenticationFilter extends OncePerRequestFilter
this.authenticationEntryPoint.commence(request, response, exception);
};
+ private AuthenticationConverter authenticationConverter = new BearerTokenAuthenticationConverter();
+
/**
* Construct a {@code BearerTokenAuthenticationFilter} using the provided parameter(s)
* @param authenticationManagerResolver
@@ -106,22 +103,21 @@ public BearerTokenAuthenticationFilter(AuthenticationManager authenticationManag
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
- String token;
+ Authentication authenticationRequest;
try {
- token = this.bearerTokenResolver.resolve(request);
+ authenticationRequest = this.authenticationConverter.convert(request);
}
- catch (OAuth2AuthenticationException invalid) {
+ catch (AuthenticationException invalid) {
this.logger.trace("Sending to authentication entry point since failed to resolve bearer token", invalid);
this.authenticationEntryPoint.commence(request, response, invalid);
return;
}
- if (token == null) {
+ if (authenticationRequest == 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);
@@ -144,10 +140,17 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
* 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");
- this.bearerTokenResolver = bearerTokenResolver;
+ 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);
}
/**
@@ -171,4 +174,15 @@ public void setAuthenticationFailureHandler(final AuthenticationFailureHandler a
this.authenticationFailureHandler = authenticationFailureHandler;
}
+ /**
+ * 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;
+ }
+
}
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
new file mode 100644
index 00000000000..8f46a381dd6
--- /dev/null
+++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationConverterTests.java
@@ -0,0 +1,87 @@
+/*
+ * 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 3882f73f72c..af4b3503703 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
@@ -187,6 +187,16 @@ public void setBearerTokenResolverWhenNullThenThrowsException() {
// @formatter:on
}
+ @Test
+ public void setAuthenticationConverterWhenNullThenThrowsException() {
+ // @formatter:off
+ BearerTokenAuthenticationFilter filter = new BearerTokenAuthenticationFilter(this.authenticationManager);
+ assertThatIllegalArgumentException()
+ .isThrownBy(() -> filter.setAuthenticationConverter(null))
+ .withMessageContaining("authenticationConverter cannot be null");
+ // @formatter:on
+ }
+
@Test
public void constructorWhenNullAuthenticationManagerThenThrowsException() {
// @formatter:off