|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright 2002-2019 the original author or authors.
|
|
|
+ * Copyright 2002-2022 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.
|
|
@@ -34,10 +34,15 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
|
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
|
|
import org.springframework.security.config.test.SpringTestContext;
|
|
|
import org.springframework.security.config.test.SpringTestContextExtension;
|
|
|
+import org.springframework.security.core.userdetails.User;
|
|
|
+import org.springframework.security.core.userdetails.UserDetailsService;
|
|
|
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
|
|
+import org.springframework.security.web.SecurityFilterChain;
|
|
|
import org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter;
|
|
|
import org.springframework.test.web.servlet.MockMvc;
|
|
|
|
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
|
+import static org.mockito.Mockito.mock;
|
|
|
import static org.mockito.Mockito.spy;
|
|
|
import static org.mockito.Mockito.verify;
|
|
|
import static org.springframework.security.config.Customizer.withDefaults;
|
|
@@ -95,6 +100,26 @@ public class X509ConfigurerTests {
|
|
|
// @formatter:on
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void x509WhenUserDetailsServiceNotConfiguredThenUsesBean() throws Exception {
|
|
|
+ this.spring.register(UserDetailsServiceBeanConfig.class).autowire();
|
|
|
+ X509Certificate certificate = loadCert("rod.cer");
|
|
|
+ // @formatter:off
|
|
|
+ this.mvc.perform(get("/").with(x509(certificate)))
|
|
|
+ .andExpect(authenticated().withUsername("rod"));
|
|
|
+ // @formatter:on
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void x509WhenUserDetailsServiceAndBeanConfiguredThenDoesNotUseBean() throws Exception {
|
|
|
+ this.spring.register(UserDetailsServiceAndBeanConfig.class).autowire();
|
|
|
+ X509Certificate certificate = loadCert("rod.cer");
|
|
|
+ // @formatter:off
|
|
|
+ this.mvc.perform(get("/").with(x509(certificate)))
|
|
|
+ .andExpect(authenticated().withUsername("rod"));
|
|
|
+ // @formatter:on
|
|
|
+ }
|
|
|
+
|
|
|
private <T extends Certificate> T loadCert(String location) {
|
|
|
try (InputStream is = new ClassPathResource(location).getInputStream()) {
|
|
|
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
|
@@ -206,4 +231,59 @@ public class X509ConfigurerTests {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ @EnableWebSecurity
|
|
|
+ static class UserDetailsServiceBeanConfig {
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
|
|
+ // @formatter:off
|
|
|
+ http
|
|
|
+ .x509(withDefaults());
|
|
|
+ // @formatter:on
|
|
|
+ return http.build();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ UserDetailsService userDetailsService() {
|
|
|
+ // @formatter:off
|
|
|
+ return new InMemoryUserDetailsManager(
|
|
|
+ User.withDefaultPasswordEncoder()
|
|
|
+ .username("rod")
|
|
|
+ .password("password")
|
|
|
+ .roles("USER", "ADMIN")
|
|
|
+ .build()
|
|
|
+ );
|
|
|
+ // @formatter:on
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @EnableWebSecurity
|
|
|
+ static class UserDetailsServiceAndBeanConfig {
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
|
|
+ // @formatter:off
|
|
|
+ UserDetailsService customUserDetailsService = new InMemoryUserDetailsManager(
|
|
|
+ User.withDefaultPasswordEncoder()
|
|
|
+ .username("rod")
|
|
|
+ .password("password")
|
|
|
+ .roles("USER", "ADMIN")
|
|
|
+ .build());
|
|
|
+ http
|
|
|
+ .x509((x509) -> x509
|
|
|
+ .userDetailsService(customUserDetailsService)
|
|
|
+ );
|
|
|
+ // @formatter:on
|
|
|
+ return http.build();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ UserDetailsService userDetailsService() {
|
|
|
+ // @formatter:off
|
|
|
+ return mock(UserDetailsService.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|