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

+ +
+ + + + + + + + + + + + + + +
Username:
Password:
+ +
+ + + \ 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()); + } +}