Add BearerTokenAuthenticationConverter
BearerTokenAuthenticationConverter is introduced to solve the problem of not being able to change AuthenticationDetailsSource. BearerTokenAuthenticationFilter delegates to BearerTokenAuthenticationConverter the task of creating BearerTokenAuthenticationToken and setting AuthenticationDetailsSource. BearerTokenAuthenticationConverter is customizable and the customized converter can be used in BearerTokenAuthenticationFilter. Closes gh-8840
This commit is contained in:
committed by
Josh Cummings
parent
efb394d3b2
commit
31f310fd22
@@ -33,6 +33,7 @@ import java.util.Map;
|
||||
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.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;
|
||||
@@ -720,6 +723,72 @@ public class OAuth2ResourceServerConfigurerTests {
|
||||
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 @@ public class OAuth2ResourceServerConfigurerTests {
|
||||
|
||||
}
|
||||
|
||||
@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 {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user