|
@@ -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 {
|
|
|
- // @formatter:off
|
|
|
- http
|
|
|
- .oauth2ResourceServer()
|
|
|
- .jwt();
|
|
|
- // @formatter:on
|
|
|
- }
|
|
|
+ AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = mock(
|
|
|
+ AuthenticationDetailsSource.class);
|
|
|
|
|
|
@Bean
|
|
|
- BearerTokenAuthenticationConverter converterOne() {
|
|
|
- BearerTokenAuthenticationConverter converter = new BearerTokenAuthenticationConverter();
|
|
|
- return converter;
|
|
|
+ SecurityFilterChain web(HttpSecurity http) throws Exception {
|
|
|
+ // @formatter:off
|
|
|
+ http
|
|
|
+ .authorizeRequests((authorize) -> authorize
|
|
|
+ .anyRequest().authenticated()
|
|
|
+ )
|
|
|
+ .oauth2ResourceServer((oauth2) -> oauth2
|
|
|
+ .jwt(withDefaults())
|
|
|
+ .withObjectPostProcessor(new ObjectPostProcessor<BearerTokenAuthenticationFilter>() {
|
|
|
+ @Override
|
|
|
+ public BearerTokenAuthenticationFilter postProcess(BearerTokenAuthenticationFilter object) {
|
|
|
+ object.setAuthenticationDetailsSource(CustomAuthenticationDetailsSource.this.authenticationDetailsSource);
|
|
|
+ return object;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ );
|
|
|
+ return http.build();
|
|
|
}
|
|
|
|
|
|
@Bean
|
|
|
- BearerTokenAuthenticationConverter converterTwo() {
|
|
|
- BearerTokenAuthenticationConverter converter = new BearerTokenAuthenticationConverter();
|
|
|
- return converter;
|
|
|
+ AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource() {
|
|
|
+ return this.authenticationDetailsSource;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
@EnableWebSecurity
|