스프링 시큐리티 기본 설정 및 테스트

This commit is contained in:
Daeil Choi
2023-01-19 14:58:29 +09:00
parent 4f6813dfe5
commit e10762afc8
8 changed files with 205 additions and 3 deletions

View File

@@ -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";
}
}

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html
lang="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Spring-Security-Study</title>
</head>
<body>
<h1>Admin</h1>
<a href="/">홈으로</a>
</body>
</html>

View File

@@ -1,5 +1,9 @@
<!doctype html>
<html lang="ko">
<!DOCTYPE HTML>
<html
lang="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
>
<head>
<meta charset="UTF-8">
<meta name="viewport"
@@ -8,6 +12,9 @@
<title>Spring-Security-Study</title>
</head>
<body>
<h1>안녕하세요</h1>
<h1>Spring Security</h1>
<a href="/user">user 페이지 바로가기</a>
<a href="/admin">admin 페이지 바로가기</a>
<a href="/logout">로그아웃</a>
</body>
</html>

View File

@@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html
lang="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Spring-Security-Study</title>
</head>
<body>
<h1>User</h1>
<a href="/">홈으로</a>
</body>
</html>

View File

@@ -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());
}
}

View File

@@ -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 {
}