Browse Source

Allow configuration of x509 through nested builder

Issue: gh-5557
pull/7099/head
Eleftheria Stein 7 years ago
parent
commit
ae9eb6f56b
  1. 36
      config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java
  2. 64
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/X509ConfigurerTests.java

36
config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java

@ -861,6 +861,42 @@ public final class HttpSecurity extends @@ -861,6 +861,42 @@ public final class HttpSecurity extends
return getOrApply(new X509Configurer<>());
}
/**
* Configures X509 based pre authentication.
*
* <h2>Example Configuration</h2>
*
* 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.
*
* <pre>
* &#064;Configuration
* &#064;EnableWebSecurity
* public class X509SecurityConfig extends WebSecurityConfigurerAdapter {
*
* &#064;Override
* protected void configure(HttpSecurity http) throws Exception {
* http
* .authorizeRequests()
* .antMatchers(&quot;/**&quot;)
* .hasRole(&quot;USER&quot;)
* .and()
* .x509(withDefaults());
* }
* }
* </pre>
*
* @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<X509Configurer<HttpSecurity>> x509Customizer) throws Exception {
x509Customizer.customize(getOrApply(new X509Configurer<>()));
return HttpSecurity.this;
}
/**
* Allows configuring of Remember Me authentication.
*

64
config/src/test/java/org/springframework/security/config/annotation/web/configurers/X509ConfigurerTests.java

@ -38,6 +38,7 @@ import java.security.cert.X509Certificate; @@ -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 { @@ -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 extends Certificate> T loadCert(String location) {
try (InputStream is = new ClassPathResource(location).getInputStream()) {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");

Loading…
Cancel
Save