์ด๋ฒ์ Spring Boot๋ฅผ ์ฌ์ฉํ์ฌ ์๋น์ค ํ๋๋ฅผ ๊ฐ๋ฐํ๊ฒ ๋์๋๋ฐ ์์ ์ฒ์๋ถํฐ ๊ฐ๋ฐํ๋ ๊ฑด ์ค๋๋ง์ด๋ผ ๋ค์ ํ๋ฒ ๋ ํผ๋ฐ์ค๋ฅผ ๋ณด๋ฉด์ Spring Security๋ฅผ ์ ์ฉํ๋ ค ํ๋ค.
์์ :
- ๊ฐ์ด๋ ์ดํด๋ณด๊ธฐ
- Spring Boot ํ๋ก์ ํธ ์์ฑ
- Spring Security ํ ์คํธ
๊ฐ์ด๋ ์ดํด๋ณด๊ธฐ
Spring์ ํํ์ด์ง์์ ๋ค์ํ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํ๊ณ ์๋ค.
์ฌ๊ธฐ์ ๋ด๊ฐ ํ์ํ ๊ฐ์ด๋๋ Securing a Web Application์ด๋๊น ํ๋ฒ ์ดํด๋ณธ๋ค.
ํ์ฌ ๊ธฐ์ค(spring security 3.1)์์๋ java 17๋ฒ์ ์ด์์ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ํ๋ค.
์ด ๊ฐ์ด๋์์๋ ๊ธฐ๋ณธ์ ์ธ๊ธฐ๋ฅ์ ์๋ ค์ฃผ๋ ๋ฐ๋ก git ์ฃผ์๋ก ๊ฐ๋ฉด ๋๋ค๊ณ ํ์ง๋ง ๋๋ ํ๋ฒ ๋ฐ๋ผํด๋ณด๊ธฐ๋ก ํ๋ค.
Spring Boot ํ๋ก์ ํธ ์์ฑ
๋จผ์ Spring Boot ํ๋ก์ ํธ๋ Spring์์ ์ ๊ณตํ๋ spring initializr๋ฅผ ์ฌ์ฉํ๋ฉด ์์ฑํ๊ธฐ ํธํ๋ค.
์ด๋ ๋๋ gradle์ ์ ํํ๊ณ ์คํ๋ง 3.1์ ์ ํํ์๋ค.
์์กด ์ชฝ์์๋ Spring Web, Spring Security, Thymeleaf๋ฅผ ์ ํํ์๋๋ฐ ๊ฐ์ด๋์์๋ ์ํ๋ฆฌํฐ๋ ๋ท๋ถ๋ถ์ gradleํ์ผ์ ์ง์ ์ถ๊ฐํด ์ฃผ์ง๋ง ๋๋ ๋ฐ๋ก ์ถ๊ฐํ์๋ค.
spring web์ ์ถ๊ฐํ ์ด์ :
spring boot์๋ ๋ด์ฅ tomcat์ด ์๋ค. speing web ์์กด์ฑ ์์ด ์คํ๋ง์ ์คํํ๋ ค๋ฉด ์ง์ ์ค์ ์ ํด์ฃผ๊ณ ๊ตฌ์กฐ์ ๋ง๊ฒ ์ธํ ํ์ฌ warํ์ผ๋ก ๋น๋ํ๊ณ ์ง์ was๋ฅผ ์คํํด์ผ์ง ์น์๋น์ค๋ก ๋์ธ ์ ์์ง๋ง spring web ์์กด์ ์ถ๊ฐํ๋ฉด ์ด๋ฐ ๋ฒ๊ฑฐ๋ก์ด ๊ฒ๋ค์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ธํ ์ ํด์ค ์ํ๋ก ์์ํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ์คํ๋ฒํผ๋ง ๋๋ฅด๋ฉด ๋์ด๋ค.
spring security๋ฅผ ์ถ๊ฐํ ์ด์ :
๋ก๊ทธ์ธ, ๊ถํ ๋ถ๋ถ์ ๊ฐ์ธ์ด ๋ฐ๋ก ๊ตฌํํด๋ ์๋ฌด๋ฐ ๋ฌธ์ ๋ ์๋ค. ๋์ ์ ๊ฒฝ ์ธ๊ฒ ์ ๋ง ๋ง์์ง๊ณ ์๊ฐ์ด ๋ง์ด ๋ ๋ค.
ํ์ง๋ง spring์ชฝ์์ ์ ๊ณตํ๋ spring security๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๊ฐ๋จํ ์ค์ ๊ณผ ์ปค์คํ ๋ง ํด์ฃผ๋ฉด ํ๋ฅญํ ๋ก๊ทธ์ธ, ๊ถํ ๋ถ๋ถ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ๋ค.
์ฌ์ฉํด๋ณด๊ณ ๊ณต๋ถํด์ ํผ์์ ์๊ฐ๋ง ์๋ค๋ฉด ๊ตฌํํ ์ ์๋ ์ ๋๊น์ง๋ ๊ผญ ํด์ผ ํ ๊ฑฐ ๊ฐ๋ค.
Thymeleaf๋ฅผ ์ถ๊ฐํ ์ด์ :
๊ฐ์ด๋์์ ์์ฑํ๊ฒ ํ๋ html์ ํ์๋ฆฌํ ์ฝ๋๊ฐ ๋ค์ด๊ฐ์๋ค.
๊ทธ ํ ํ๋ก์ ํธ๋ฅผ IDE๋ฅผ ์ฌ์ฉํ์ฌ ์ด์ด์ฃผ๊ณ gradle ๋๋ maven ๋น๋๋ฅผ ํด์ค๋๋ค.
์ด๋ java, gradle, maven ๋ฒ์ ์ ์ ํ์ธํ๋ค.
gradle ๋๋ maven ๋น๋๋ฅผ ํตํด ์์กด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ๊ฐ์ ธ์์ผ๋ฉด ์ฑ๊ณต์ด๋ค.
Spring Security ํ ์คํธ
ํ ์คํธ๋ฅผ ํ๊ธฐ ์ํด์ ํ๋ฉด์ด ํ์ํ๋ค ๊ฐ์ด๋์์ ์ ๊ณตํ๋ ํ๋ฉด์ ๊ทธ๋๋ก ์ฌ์ฉํด๋ณด์.
- src/main/java/com/example/securingweb/MvcConfig.java
package com.example.securingweb;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/login").setViewName("login");
}
}
- src/main/resources/templates/home.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<title>Spring Security Example</title>
</head>
<body>
<h1>Welcome!</h1>
<p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>
</body>
</html>
- src/main/resources/templates/hello.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<title>Hello World!</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
์ด๋ ๊ฒ 2๊ฐ ์ถ๊ฐํด๋๊ณ ์๋น์ค๋ฅผ ์คํํ๊ณ localhost:8080 ์ฃผ์๋ฅผ ์ ๋ ฅํด์ ๋ค์ด๊ฐ๋ณด๋ฉด ์ ๊ธฐํ ๋ก๊ทธ์ธ ํ๋ฉด์ด ๋ณด์ธ๋ค.
์ด๊ฑด Spring Security์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ ๋ก๊ทธ์ธ ํ์ด์ง์ด๊ณ ๋ค๋ฅธ url์ ์ ๋ ฅํด๋ http://localhost:8080/login ๋ก๋ง redirect๋๋๊ฑธ ํ์ธํ ์ ์๋ค.
์ค์ ๋ ์์์ ์ธํ ๋์ด์๋ ์ํ์ธ๋ฐ ์ด๋ ์กฐ๊ธ ์ปค์คํ ์ ํ๊ธฐ ์ํด์๋ ์ฐ๋ฆฌ๊ฐ ์ง์ ์ค์ ํด์ ์ฐ๊ฒ ๋ค๋ ๊ฑธ ์๋ ค์ผ ํ๋ค.
@EnableWebSecurity ๋ฅผ ์ ์ํจ์ผ๋ก์จ WebSecurityConfig๋ ์ํ๋ฆฌํฐ ๊ด๋ จ ์ค์ ์ ๋ด๋นํ๋ ํด๋์ค๋ก ์ ์ํ์๋ค.
๊ทธ๋ฆฌ๊ณ securityFilterChain๋ฉ์๋์์๋ SecurityFilterChain์ returnํ๋๋ฐ ์ฌ๊ธฐ์ /, /home์ผ๋ก ๋ค์ด์ค๋ ์์ฒญ์ ์๋ฌด๋ ์ ๊ทผ๊ฐ๋ฅํ๊ฒ ํ์๊ณ ์ด์ธ ๋ชจ๋ url์ ๋ํด์๋ ์ธ์ฆ๋ ์ํ์ฌ์ผ์ง๋ง ๋์ด๊ฐ ์ ์๋ ์ํ๋ฅผ ์ฃผ์๋ค. ๊ทธ๋ฆฌ๊ณ ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋ณด๋ด๋ ์ค์ ์ ํ๋ค.
- src/main/java/com/example/securingweb/WebSecurityConfig.java
package com.example.securingweb;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
)
.formLogin((form) -> form
.loginPage("/login")
.permitAll()
)
.logout((logout) -> logout.permitAll());
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user =
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
- src/main/resources/templates/login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<title>Spring Security Example </title>
</head>
<body>
<div th:if="${param.error}">
Invalid username and password.
</div>
<div th:if="${param.logout}">
You have been logged out.
</div>
<form th:action="@{/login}" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Sign In"/></div>
</form>
</body>
</html>
์ ์ฝ๋๋ฅผ ๋ค ์ถ๊ฐํ๊ณ ์คํํด์ localhost:8080์ผ๋ก ์ ๊ทผํด ๋ณด๋ฉด
home.html๋ด์ฉ์ด ๋์ค๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
ํ์ดํผ๋งํฌ๊ฐ ๊ฑธ๋ฆฐ here๋ถ๋ถ์ ํด๋ฆญํ๋ฉด localhost:8080/hello ์ชฝ์ผ๋ก ๋ณด๋ด์ง๋ง ์ฐ๋ฆฐ ์ค์ ์์ /hello๋ ์ธ์ฆ๋ ํ์๋ง ์ ๊ทผํ ์ ์๊ฒ ํ์๊ธฐ ๋๋ฌธ์ loginํ์ด์ง๋ฅผ ํ์ธํ ์ ์๋ค.
์ง๊ธ์ ์ ์ ๊ฐ ๋ฐ๋ก ์๊ธฐ์ WebSecurityConfig์ ์ถ๊ฐ๋์ด ์๋ UserDetailsService๋ถ๋ถ์ ์์๋ก ์ถ๊ฐ๋์ด์๋ ํ์์ผ๋ก ๋ก๊ทธ์ธํ์(user/password)
๊ทธ ํ hello ์ชฝ์ผ๋ก ์ ๊ทผํ๋ฉด ์ ์ถ๋ ฅ๋๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
๋ค์ ๊ฒ์๊ธ์๋ ์ข ๋ ์ปค์คํ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์ฑํด๋ด์ผ๊ฒ ๋ค.
๐