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 7c1acd7200..7d8654687d 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
@@ -751,6 +751,86 @@ public final class HttpSecurity extends
return getOrApply(new JeeConfigurer<>());
}
+ /**
+ * Configures container based pre authentication. In this case, authentication
+ * is managed by the Servlet Container.
+ *
+ *
Example Configuration
+ *
+ * The following configuration will use the principal found on the
+ * {@link HttpServletRequest} and if the user is in the role "ROLE_USER" or
+ * "ROLE_ADMIN" will add that to the resulting {@link Authentication}.
+ *
+ *
+ * @Configuration
+ * @EnableWebSecurity
+ * public class JeeSecurityConfig extends WebSecurityConfigurerAdapter {
+ *
+ * @Override
+ * protected void configure(HttpSecurity http) throws Exception {
+ * http
+ * .authorizeRequests()
+ * .antMatchers("/**").hasRole("USER")
+ * .and()
+ * .jee(jee ->
+ * jee
+ * .mappableRoles("USER", "ADMIN")
+ * );
+ * }
+ * }
+ *
+ *
+ * Developers wishing to use pre authentication with the container will need to ensure
+ * their web.xml configures the security constraints. For example, the web.xml (there
+ * is no equivalent Java based configuration supported by the Servlet specification)
+ * might look like:
+ *
+ *
+ * <login-config>
+ * <auth-method>FORM</auth-method>
+ * <form-login-config>
+ * <form-login-page>/login</form-login-page>
+ * <form-error-page>/login?error</form-error-page>
+ * </form-login-config>
+ * </login-config>
+ *
+ * <security-role>
+ * <role-name>ROLE_USER</role-name>
+ * </security-role>
+ * <security-constraint>
+ * <web-resource-collection>
+ * <web-resource-name>Public</web-resource-name>
+ * <description>Matches unconstrained pages</description>
+ * <url-pattern>/login</url-pattern>
+ * <url-pattern>/logout</url-pattern>
+ * <url-pattern>/resources/*</url-pattern>
+ * </web-resource-collection>
+ * </security-constraint>
+ * <security-constraint>
+ * <web-resource-collection>
+ * <web-resource-name>Secured Areas</web-resource-name>
+ * <url-pattern>/*</url-pattern>
+ * </web-resource-collection>
+ * <auth-constraint>
+ * <role-name>ROLE_USER</role-name>
+ * </auth-constraint>
+ * </security-constraint>
+ *
+ *
+ * Last you will need to configure your container to contain the user with the correct
+ * roles. This configuration is specific to the Servlet Container, so consult your
+ * Servlet Container's documentation.
+ *
+ * @param jeeCustomizer the {@link Customizer} to provide more options for
+ * the {@link JeeConfigurer}
+ * @return the {@link HttpSecurity} for further customizations
+ * @throws Exception
+ */
+ public HttpSecurity jee(Customizer> jeeCustomizer) throws Exception {
+ jeeCustomizer.customize(getOrApply(new JeeConfigurer<>()));
+ return HttpSecurity.this;
+ }
+
/**
* Configures X509 based pre authentication.
*
diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/JeeConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/JeeConfigurerTests.java
index fac4baf354..c55ad59f47 100644
--- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/JeeConfigurerTests.java
+++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/JeeConfigurerTests.java
@@ -25,6 +25,9 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
+import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource;
import org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter;
import org.springframework.test.web.servlet.MockMvc;
@@ -125,4 +128,112 @@ public class JeeConfigurerTests {
// @formatter:on
}
}
+
+ @Test
+ public void requestWhenJeeMappableRolesInLambdaThenAuthenticatedWithMappableRoles() throws Exception {
+ this.spring.register(JeeMappableRolesConfig.class).autowire();
+ Principal user = mock(Principal.class);
+ when(user.getName()).thenReturn("user");
+
+ this.mvc.perform(get("/")
+ .principal(user)
+ .with(request -> {
+ request.addUserRole("ROLE_ADMIN");
+ request.addUserRole("ROLE_USER");
+ return request;
+ }))
+ .andExpect(authenticated().withRoles("USER"));
+ }
+
+ @EnableWebSecurity
+ public static class JeeMappableRolesConfig extends WebSecurityConfigurerAdapter {
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ // @formatter:off
+ http
+ .authorizeRequests()
+ .anyRequest().hasRole("USER")
+ .and()
+ .jee(jee ->
+ jee
+ .mappableRoles("USER")
+ );
+ // @formatter:on
+ }
+ }
+
+ @Test
+ public void requestWhenJeeMappableAuthoritiesInLambdaThenAuthenticatedWithMappableAuthorities() throws Exception {
+ this.spring.register(JeeMappableAuthoritiesConfig.class).autowire();
+ Principal user = mock(Principal.class);
+ when(user.getName()).thenReturn("user");
+
+ this.mvc.perform(get("/")
+ .principal(user)
+ .with(request -> {
+ request.addUserRole("ROLE_ADMIN");
+ request.addUserRole("ROLE_USER");
+ return request;
+ }))
+ .andExpect(authenticated().withAuthorities(AuthorityUtils.createAuthorityList("ROLE_USER")));
+ }
+
+ @EnableWebSecurity
+ public static class JeeMappableAuthoritiesConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ // @formatter:off
+ http
+ .authorizeRequests()
+ .anyRequest().hasRole("USER")
+ .and()
+ .jee(jee ->
+ jee
+ .mappableAuthorities("ROLE_USER")
+ );
+ // @formatter:on
+ }
+ }
+
+ @Test
+ public void requestWhenCustomAuthenticatedUserDetailsServiceInLambdaThenCustomAuthenticatedUserDetailsServiceUsed()
+ throws Exception {
+ this.spring.register(JeeCustomAuthenticatedUserDetailsServiceConfig.class).autowire();
+ Principal user = mock(Principal.class);
+ User userDetails = new User("user", "N/A", true, true, true, true,
+ AuthorityUtils.createAuthorityList("ROLE_USER"));
+ when(user.getName()).thenReturn("user");
+ when(JeeCustomAuthenticatedUserDetailsServiceConfig.authenticationUserDetailsService.loadUserDetails(any()))
+ .thenReturn(userDetails);
+
+ this.mvc.perform(get("/")
+ .principal(user)
+ .with(request -> {
+ request.addUserRole("ROLE_ADMIN");
+ request.addUserRole("ROLE_USER");
+ return request;
+ }))
+ .andExpect(authenticated().withRoles("USER"));
+ }
+
+ @EnableWebSecurity
+ public static class JeeCustomAuthenticatedUserDetailsServiceConfig extends WebSecurityConfigurerAdapter {
+ static AuthenticationUserDetailsService authenticationUserDetailsService =
+ mock(AuthenticationUserDetailsService.class);
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ // @formatter:off
+ http
+ .authorizeRequests()
+ .anyRequest().hasRole("USER")
+ .and()
+ .jee(jee ->
+ jee
+ .authenticatedUserDetailsService(authenticationUserDetailsService)
+ );
+ // @formatter:on
+ }
+ }
}