From e10762afc8068c7da897367e4e36b2b2baca27d3 Mon Sep 17 00:00:00 2001 From: Daeil Choi Date: Thu, 19 Jan 2023 14:58:29 +0900 Subject: [PATCH] =?UTF-8?q?=EC=8A=A4=ED=94=84=EB=A7=81=20=EC=8B=9C?= =?UTF-8?q?=ED=81=90=EB=A6=AC=ED=8B=B0=20=EA=B8=B0=EB=B3=B8=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../springsecuritystudy/HomeController.java | 19 +++++ .../springsecuritystudy/SecurityConfig.java | 47 ++++++++++++ src/main/resources/application.yml | 8 ++ src/main/resources/templates/admin.html | 18 +++++ src/main/resources/templates/index.html | 13 +++- src/main/resources/templates/user.html | 18 +++++ .../HomeControllerTest.java | 74 +++++++++++++++++++ .../springsecuritystudy/WithMockAdmin.java | 11 +++ 8 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/example/springsecuritystudy/HomeController.java create mode 100644 src/main/java/com/example/springsecuritystudy/SecurityConfig.java create mode 100644 src/main/resources/templates/admin.html create mode 100644 src/main/resources/templates/user.html create mode 100644 src/test/java/com/example/springsecuritystudy/HomeControllerTest.java create mode 100644 src/test/java/com/example/springsecuritystudy/WithMockAdmin.java diff --git a/src/main/java/com/example/springsecuritystudy/HomeController.java b/src/main/java/com/example/springsecuritystudy/HomeController.java new file mode 100644 index 0000000..ac81a70 --- /dev/null +++ b/src/main/java/com/example/springsecuritystudy/HomeController.java @@ -0,0 +1,19 @@ +package com.example.springsecuritystudy; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class HomeController { + + @GetMapping("/user") + public String user() { + return "user"; + } + + @GetMapping("/admin") + public String admin() { + return "admin"; + } + +} diff --git a/src/main/java/com/example/springsecuritystudy/SecurityConfig.java b/src/main/java/com/example/springsecuritystudy/SecurityConfig.java new file mode 100644 index 0000000..cec72d5 --- /dev/null +++ b/src/main/java/com/example/springsecuritystudy/SecurityConfig.java @@ -0,0 +1,47 @@ +package com.example.springsecuritystudy; + +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; + +@EnableWebSecurity +public class SecurityConfig { + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests(authorize -> authorize + .antMatchers("/user").hasRole("USER") + .antMatchers("/admin").hasRole("ADMIN") + .anyRequest().authenticated() + ) + .httpBasic(Customizer.withDefaults()) + .formLogin(Customizer.withDefaults()) + .logout() + .logoutSuccessUrl("/login") + ; + return http.build(); + } + + @Bean + public UserDetailsService users() { + User.UserBuilder users = User.withDefaultPasswordEncoder(); + UserDetails user = users + .username("user") + .password("user") + .roles("USER") + .build(); + UserDetails admin = users + .username("admin") + .password("admin") + .roles("ADMIN") + .build(); + return new InMemoryUserDetailsManager(user, admin); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index fd2cd1d..b2809b0 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,14 @@ server: port: 8080 + devtools: + livereload: + enabled: true + restart: + enabled: true + thymeleaf: + cache: false logging: level: root: info +# org.springframework.security: debug diff --git a/src/main/resources/templates/admin.html b/src/main/resources/templates/admin.html new file mode 100644 index 0000000..7bdc29f --- /dev/null +++ b/src/main/resources/templates/admin.html @@ -0,0 +1,18 @@ + + + + + + + Spring-Security-Study + + +

Admin

+ 홈으로 + + diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index b42893c..f541a3f 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -1,5 +1,9 @@ - - + + Spring-Security-Study -

안녕하세요

+

Spring Security

+ user 페이지 바로가기 + admin 페이지 바로가기 + 로그아웃 diff --git a/src/main/resources/templates/user.html b/src/main/resources/templates/user.html new file mode 100644 index 0000000..b20e657 --- /dev/null +++ b/src/main/resources/templates/user.html @@ -0,0 +1,18 @@ + + + + + + + Spring-Security-Study + + +

User

+ 홈으로 + + diff --git a/src/test/java/com/example/springsecuritystudy/HomeControllerTest.java b/src/test/java/com/example/springsecuritystudy/HomeControllerTest.java new file mode 100644 index 0000000..09c7b98 --- /dev/null +++ b/src/test/java/com/example/springsecuritystudy/HomeControllerTest.java @@ -0,0 +1,74 @@ +package com.example.springsecuritystudy; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.test.context.support.WithMockUser; +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.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@SpringBootTest +class HomeControllerTest { + + @Autowired + private WebApplicationContext applicationContext; + private MockMvc mvc; + + @BeforeEach + public void setUp() { + mvc = MockMvcBuilders.webAppContextSetup(applicationContext) + .apply(springSecurity()) + .alwaysDo(print()) + .build(); + } + + @Test + void login_user() throws Exception { + mvc.perform( + formLogin("/login") + .user("user") + .password("user") + ).andExpect(status().is3xxRedirection()); + } + + @Test + void login_admin() throws Exception { + mvc.perform( + formLogin("/login") + .user("admin") + .password("admin") + ).andExpect(status().is3xxRedirection()); + } + + @Test + @WithMockUser + void access_user() throws Exception { + mvc.perform( + get("/user") + ).andExpect(status().isOk()); + } + + @Test + @WithMockAdmin + void access_admin() throws Exception { + mvc.perform( + get("/admin") + ).andExpect(status().isOk()); + } + + @Test + @WithMockUser + void access_denied() throws Exception { + mvc.perform( + get("/admin") + ).andExpect(status().isForbidden()); + } +} diff --git a/src/test/java/com/example/springsecuritystudy/WithMockAdmin.java b/src/test/java/com/example/springsecuritystudy/WithMockAdmin.java new file mode 100644 index 0000000..274d751 --- /dev/null +++ b/src/test/java/com/example/springsecuritystudy/WithMockAdmin.java @@ -0,0 +1,11 @@ +package com.example.springsecuritystudy; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import org.springframework.security.test.context.support.WithMockUser; + +@Retention(RetentionPolicy.RUNTIME) +@WithMockUser(value="admin", roles="ADMIN") +public @interface WithMockAdmin { +}