diff --git a/spring-security-mvc-boot/pom.xml b/spring-security-mvc-boot/pom.xml
index 591ededccf..16535b09a7 100644
--- a/spring-security-mvc-boot/pom.xml
+++ b/spring-security-mvc-boot/pom.xml
@@ -18,15 +18,20 @@
+
org.springframework.boot
spring-boot-starter-security
-
+
org.springframework.boot
spring-boot-starter-web
-
+
+ org.apache.tomcat
+ tomcat-catalina
+ ${tomcat.version}
+
org.springframework.boot
spring-boot-starter-tomcat
@@ -54,13 +59,13 @@
com.h2database
h2
-
+
org.springframework.boot
spring-boot-starter-test
test
-
+
junit
junit
@@ -97,6 +102,12 @@
spring-test
test
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
org.apache.derby
@@ -140,7 +151,7 @@
jstl-api
${jstl.version}
-
+
@@ -158,6 +169,7 @@
**/*IntegrationTest.java
**/*LiveTest.java
+ **/*EntryPointsTest.java
@@ -279,6 +291,43 @@
+
+
+ entryPoints
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ integration-test
+
+ test
+
+
+
+ **/*LiveTest.java
+ **/*IntegrationTest.java
+
+
+ **/*EntryPointsTest.java
+
+
+
+
+
+
+ json
+
+
+
+
+
+
+
@@ -288,12 +337,17 @@
+
+
+
UTF-8
1.8
10.13.1.1
1.1.2
4.2.0.RELEASE
- 4.2.0.RELEASE
+ 4.2.0.RELEASE
+ 4.2.0.RELEASE
+ 8.5.11
1.2
2.4.0
diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java b/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java
index 03de5897f5..ae2651c06f 100644
--- a/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java
+++ b/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java
@@ -9,7 +9,8 @@ import org.springframework.context.annotation.FilterType;
@Configuration
@EnableAutoConfiguration
-@ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.voter.*"), @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multiplelogin.*") })
+@ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.voter.*"), @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multiplelogin.*"),
+ @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multipleentrypoints.*") })
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java
new file mode 100644
index 0000000000..4e5fafcd99
--- /dev/null
+++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java
@@ -0,0 +1,12 @@
+package org.baeldung.multipleentrypoints;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+// @ImportResource({"classpath*:spring-security-multiple-entry.xml"})
+public class MultipleEntryPointsApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(MultipleEntryPointsApplication.class, args);
+ }
+}
diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java
new file mode 100644
index 0000000000..9da2ef20e3
--- /dev/null
+++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java
@@ -0,0 +1,79 @@
+package org.baeldung.multipleentrypoints;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+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.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+
+@Configuration
+@EnableWebSecurity
+public class MultipleEntryPointsSecurityConfig {
+
+ @Bean
+ public UserDetailsService userDetailsService() throws Exception {
+ InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
+ manager.createUser(User.withUsername("user").password("userPass").roles("USER").build());
+ manager.createUser(User.withUsername("admin").password("adminPass").roles("ADMIN").build());
+ return manager;
+ }
+
+ @Configuration
+ @Order(1)
+ public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter {
+
+ public App1ConfigurationAdapter() {
+ super();
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ //@formatter:off
+ http.antMatcher("/admin/**")
+ .authorizeRequests().anyRequest().hasRole("ADMIN")
+ .and().httpBasic()
+ .and().exceptionHandling().accessDeniedPage("/403");
+ //@formatter:on
+ }
+ }
+
+ @Configuration
+ @Order(2)
+ public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter {
+
+ public App2ConfigurationAdapter() {
+ super();
+ }
+
+ protected void configure(HttpSecurity http) throws Exception {
+ //@formatter:off
+ http.antMatcher("/user/**")
+ .authorizeRequests().anyRequest().hasRole("USER")
+ .and().formLogin().loginPage("/userLogin").loginProcessingUrl("/user/login")
+ .failureUrl("/userLogin?error=loginError").defaultSuccessUrl("/user/myUserPage")
+ .and().logout().logoutUrl("/user/logout").logoutSuccessUrl("/multipleHttpLinks")
+ .deleteCookies("JSESSIONID")
+ .and().exceptionHandling().accessDeniedPage("/403")
+ .and().csrf().disable();
+ //@formatter:on
+ }
+ }
+
+ @Configuration
+ @Order(3)
+ public static class App3ConfigurationAdapter extends WebSecurityConfigurerAdapter {
+
+ public App3ConfigurationAdapter() {
+ super();
+ }
+
+ protected void configure(HttpSecurity http) throws Exception {
+ http.antMatcher("/guest/**").authorizeRequests().anyRequest().permitAll();
+ }
+ }
+
+}
diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/PagesController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/PagesController.java
new file mode 100644
index 0000000000..3b59678b87
--- /dev/null
+++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/PagesController.java
@@ -0,0 +1,38 @@
+package org.baeldung.multipleentrypoints;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class PagesController {
+
+ @RequestMapping("/multipleHttpLinks")
+ public String getMultipleHttpLinksPage() {
+ return "multipleHttpElems/multipleHttpLinks";
+ }
+
+ @RequestMapping("/admin/myAdminPage")
+ public String getAdminPage() {
+ return "multipleHttpElems/myAdminPage";
+ }
+
+ @RequestMapping("/user/myUserPage")
+ public String getUserPage() {
+ return "multipleHttpElems/myUserPage";
+ }
+
+ @RequestMapping("/guest/myGuestPage")
+ public String getGuestPage() {
+ return "multipleHttpElems/myGuestPage";
+ }
+
+ @RequestMapping("/userLogin")
+ public String getUserLoginPage() {
+ return "multipleHttpElems/login";
+ }
+
+ @RequestMapping("/403")
+ public String getAccessDeniedPage() {
+ return "403";
+ }
+}
diff --git a/spring-security-mvc-boot/src/main/resources/spring-security-multiple-entry.xml b/spring-security-mvc-boot/src/main/resources/spring-security-multiple-entry.xml
new file mode 100644
index 0000000000..1a68bd5c30
--- /dev/null
+++ b/spring-security-mvc-boot/src/main/resources/spring-security-multiple-entry.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/login.html b/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/login.html
new file mode 100644
index 0000000000..2119baec66
--- /dev/null
+++ b/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/login.html
@@ -0,0 +1,27 @@
+
+
+
+
+ Login
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html b/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html
new file mode 100644
index 0000000000..4a2af1d649
--- /dev/null
+++ b/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html
@@ -0,0 +1,16 @@
+
+
+
+
+Multiple Http Elements Links
+
+
+
+Admin page
+
+User page
+
+Guest page
+
+
+
\ No newline at end of file
diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myAdminPage.html b/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myAdminPage.html
new file mode 100644
index 0000000000..3003833562
--- /dev/null
+++ b/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myAdminPage.html
@@ -0,0 +1,13 @@
+
+
+
+
+Admin Page
+
+
+Welcome admin!
+
+
+Back to links
+
+
\ No newline at end of file
diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myGuestPage.html b/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myGuestPage.html
new file mode 100644
index 0000000000..47a4c9c44a
--- /dev/null
+++ b/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myGuestPage.html
@@ -0,0 +1,13 @@
+
+
+
+
+Guest Page
+
+
+Welcome guest!
+
+
+Back to links
+
+
\ No newline at end of file
diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myUserPage.html b/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myUserPage.html
new file mode 100644
index 0000000000..f6c2def0b8
--- /dev/null
+++ b/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myUserPage.html
@@ -0,0 +1,13 @@
+
+
+
+
+User Page
+
+
+Welcome user! Logout
+
+
+Back to links
+
+
\ No newline at end of file
diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsTest.java
new file mode 100644
index 0000000000..96d38d4943
--- /dev/null
+++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsTest.java
@@ -0,0 +1,64 @@
+package org.baeldung.web;
+
+import org.baeldung.multipleentrypoints.MultipleEntryPointsApplication;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.security.web.FilterChainProxy;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
+
+@RunWith(SpringRunner.class)
+@WebAppConfiguration
+@SpringBootTest(classes = MultipleEntryPointsApplication.class)
+public class MultipleEntryPointsTest {
+ @Autowired
+ private WebApplicationContext wac;
+
+ @Autowired
+ private FilterChainProxy springSecurityFilterChain;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).addFilter(springSecurityFilterChain).build();
+ }
+
+ @Test
+ public void whenTestAdminCredentials_thenOk() throws Exception {
+ mockMvc.perform(get("/admin/myAdminPage")).andExpect(status().isUnauthorized());
+
+ mockMvc.perform(get("/admin/myAdminPage").with(httpBasic("admin", "adminPass"))).andExpect(status().isOk());
+
+ mockMvc.perform(get("/user/myUserPage").with(user("admin").password("adminPass").roles("ADMIN"))).andExpect(status().isForbidden());
+
+ }
+
+ @Test
+ public void whenTestUserCredentials_thenOk() throws Exception {
+ mockMvc.perform(get("/user/myUserPage")).andExpect(status().isFound());
+
+ mockMvc.perform(get("/user/myUserPage").with(user("user").password("userPass").roles("USER"))).andExpect(status().isOk());
+
+ mockMvc.perform(get("/admin/myAdminPage").with(user("user").password("userPass").roles("USER"))).andExpect(status().isForbidden());
+ }
+
+ @Test
+ public void givenAnyUser_whenGetGuestPage_thenOk() throws Exception {
+ mockMvc.perform(get("/guest/myGuestPage")).andExpect(status().isOk());
+
+ mockMvc.perform(get("/guest/myGuestPage").with(user("user").password("userPass").roles("USER"))).andExpect(status().isOk());
+
+ mockMvc.perform(get("/guest/myGuestPage").with(httpBasic("admin", "adminPass"))).andExpect(status().isOk());
+ }
+}