diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java b/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java
index 7d8654687d..3bd002b5e8 100644
--- a/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java
+++ b/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java
@@ -861,6 +861,42 @@ public final class HttpSecurity extends
return getOrApply(new X509Configurer<>());
}
+ /**
+ * Configures X509 based pre authentication.
+ *
+ *
Example Configuration
+ *
+ * The following configuration will attempt to extract the username from the X509
+ * certificate. Remember that the Servlet Container will need to be configured to
+ * request client certificates in order for this to work.
+ *
+ *
+ * @Configuration
+ * @EnableWebSecurity
+ * public class X509SecurityConfig extends WebSecurityConfigurerAdapter {
+ *
+ * @Override
+ * protected void configure(HttpSecurity http) throws Exception {
+ * http
+ * .authorizeRequests()
+ * .antMatchers("/**")
+ * .hasRole("USER")
+ * .and()
+ * .x509(withDefaults());
+ * }
+ * }
+ *
+ *
+ * @param x509Customizer the {@link Customizer} to provide more options for
+ * the {@link X509Configurer}
+ * @return the {@link HttpSecurity} for further customizations
+ * @throws Exception
+ */
+ public HttpSecurity x509(Customizer> x509Customizer) throws Exception {
+ x509Customizer.customize(getOrApply(new X509Configurer<>()));
+ return HttpSecurity.this;
+ }
+
/**
* Allows configuring of Remember Me authentication.
*
diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/X509ConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/X509ConfigurerTests.java
index 49ca4e431b..f7c24c0013 100644
--- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/X509ConfigurerTests.java
+++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/X509ConfigurerTests.java
@@ -38,6 +38,7 @@ import java.security.cert.X509Certificate;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.springframework.security.config.Customizer.withDefaults;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.x509;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -122,6 +123,69 @@ public class X509ConfigurerTests {
}
}
+ @Test
+ public void x509WhenConfiguredInLambdaThenUsesDefaults() throws Exception {
+ this.spring.register(DefaultsInLambdaConfig.class).autowire();
+ X509Certificate certificate = loadCert("rod.cer");
+
+ this.mvc.perform(get("/")
+ .with(x509(certificate)))
+ .andExpect(authenticated().withUsername("rod"));
+ }
+
+ @EnableWebSecurity
+ static class DefaultsInLambdaConfig extends WebSecurityConfigurerAdapter {
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ // @formatter:off
+ http
+ .x509(withDefaults());
+ // @formatter:on
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ // @formatter:off
+ auth
+ .inMemoryAuthentication()
+ .withUser("rod").password("password").roles("USER", "ADMIN");
+ // @formatter:on
+ }
+ }
+
+ @Test
+ public void x509WhenSubjectPrincipalRegexInLambdaThenUsesRegexToExtractPrincipal() throws Exception {
+ this.spring.register(SubjectPrincipalRegexInLambdaConfig.class).autowire();
+ X509Certificate certificate = loadCert("rodatexampledotcom.cer");
+
+ this.mvc.perform(get("/")
+ .with(x509(certificate)))
+ .andExpect(authenticated().withUsername("rod"));
+ }
+
+ @EnableWebSecurity
+ static class SubjectPrincipalRegexInLambdaConfig extends WebSecurityConfigurerAdapter {
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ // @formatter:off
+ http
+ .x509(x509 ->
+ x509
+ .subjectPrincipalRegex("CN=(.*?)@example.com(?:,|$)")
+ );
+ // @formatter:on
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ // @formatter:off
+ auth
+ .inMemoryAuthentication()
+ .withUser("rod").password("password").roles("USER", "ADMIN");
+ // @formatter:on
+ }
+ }
+
private T loadCert(String location) {
try (InputStream is = new ClassPathResource(location).getInputStream()) {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");