2022. 8. 10. 02:30ใBack-End ์์ ์ค/Spring Framework
์ด ๊ธ์ ์ธํ๋ฐ - Spring Boot ๊ธฐ๋ฐ์ผ๋ก ๊ฐ๋ฐํ๋ Spring Security๋ฅผ ํ์ตํ๋ฉด์ ์ ๋ฆฌํ ๋ด์ฉ ์ ๋๋ค.
GIT HUB ์ฃผ์ : https://github.com/junyharang-coding-study/spring-security
๐ ๋ชฉ์ฐจ
โ [Spring Boot] Spring Security Basic - ๊ธฐ๋ณธ API ๋ฐ Filter ์ดํดํธ
โ [Stpring Boot] Spring Security Basic - Spring Security ์ฃผ์ ์ํคํ
์ฒ ์ดํดํธ
โ [Stpring Boot] Spring Security ์ค์ ํ๋ก์ ํธ - ์ธ์ฆ ํ๋ก์ธ์ค Form ์ธ์ฆ ๊ตฌํ(1)
โ [Stpring Boot] Spring Security ์ค์ ํ๋ก์ ํธ - ์ธ์ฆ ํ๋ก์ธ์ค Form ์ธ์ฆ ๊ตฌํ(2)
โ [Stpring Boot] Spring Security ์ค์ ํ๋ก์ ํธ - ์ธ์ฆ ํ๋ก์ธ์ค Ajax ์ธ์ฆ ๊ตฌํ
๐ Spring Security ์ด๋ก
๐ฝ ์ค๋นํ๊ธฐ
๐ฆ ๊ฐ๋ฐ ํ๊ฒฝ
• JDK 1.8 ์ด์
• Maven
• DB - H2 DB
• IDE - InteliJ
๐ฆ ํ๋ก์ ํธ ๊ตฌ์ฑ ๋ฐ ์์กด์ฑ ์ถ๊ฐ
์ต์ด Project ๊ตฌ์ฑ ์ ์์กด์ฑ์ Spring Boot Web๋ง ์ถ๊ฐ ํ์์ต๋๋ค.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>security</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>junyharang-spring-secutiry</name>
<description>junyharang-spring-secutiry</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security Dependency ์ถ๊ฐ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Slf4J Dependency ์ถ๊ฐ -->
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
๊ทธ๋ฐ ๋ค ์์ ๊ฐ์ด Spring Security Dependency์ Log ์ถ๋ ฅ์ ์ํ Slf4J Dependency๋ฅผ ์ถ๊ฐํด ์ฃผ์์ด์!
๐ฝ Spring Security Basic API & Filter ์ดํดํ๊ธฐ
๐ฆ ์ธ์ฆ API - Spring Security ์์กด์ฑ ์ถ๊ฐ ์ ์ผ์ด๋๋ ์ผ
Spring Boot Server๋ฅผ ๊ธฐ๋์ํค๋ฉด Spring Security์ ์ด๊ธฐํ ์์
๋ฐ ๋ณด์ ์ค์ ์ด ์ด๋ฃจ์ด์ง๊ฒ ๋์.
๋ณ๋์ ์ค์ , ๊ตฌํ์ ํ์ง ์์๋ ๊ธฐ๋ณธ์ ์ธ ์น ๋ณด์ ๊ธฐ๋ฅ์ด ์๋ํ๊ฒ ๋๋ต๋๋ค.
• ๋ชจ๋ ์์ฒญ์ ์ธ์ฆ์ด ๋์ด์ผ ์์ ์ ๊ทผ ๊ฐ๋ฅ
• ์ธ์ฆ ๋ฐฉ์์ Form Login ๋ฐฉ์, Http Basic Login ๋ฐฉ์ ์ ๊ณต
• ๊ธฐ๋ณธ Login Page ์ ๊ณต
• ๊ธฐ๋ณธ ๊ณ์ ํ ๊ฐ ์ ๊ณต - username(ID) : user / password : ๋๋ค ๋ฌธ์์ด (Spring Boot ๊ธฐ๋ ์ ์๋์ ๊ฐ์ด ํ์)
ํ์ง๋ง, Spring Security ์ด๊ธฐ์๋ ์๋์ ๊ฐ์ ๋ฌธ์ ์ ์ด ์๋ ๊ฒ์ด์์.
• ๊ณ์ ์ถ๊ฐ
• Data Base ์ถ๊ฐ ๋ฐ ์ฐ๋
• ๊ธฐ๋ณธ ๋ณด์ ๊ธฐ๋ฅ ์ธ ์ธ๋ถ์ ์ถ๊ฐ์ ๋ณด์ ๊ธฐ๋ฅ ๊ตฌํ ํ์
๐ฆ ์ธ์ฆ API - ์ด์ฉ์ ์ ์ ๋ณด์ ๊ธฐ๋ฅ ๊ตฌํ
์ต์ด Spring Security๋ฅผ ์ด์ฉํ๊ธฐ ์ํด ์๋์ ๊ฐ์ ๋ฐฉ์์ ์ด์ฉํด์ ์ค์ ์ ํด ์ฃผ์ด์ผ ํด์.
1. ์ธ์ฆ API ์ ๊ณต ๊ธฐ๋ฅ
• http.formLogin()
• http.logout()
• http.csrf()
• http.httpBasic()
• http.SessionManagement()
• http.RememberMe()
• http.ExceptionHandling()
• http.addFilter()
2. ์ธ๊ฐ API ์ ๊ณต ๊ธฐ๋ฅ
• http.authorizeRequests()
• .antMatchers("/{URI}")
• .hasRole({๊ณ์ ๊ถํ๋ช
})
• .permitAll()
• authenticated()
• fullyAuthentication()
• access(hasRole({๊ณ์ ๊ถํ๋ช
})
• . denyAll()
๐ฆ ์ธ์ฆ API - SecurityConfig ๊ตฌํ
package com.junyharang.spring.security.config;
import lombok.extern.slf4j.Slf4j;
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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Spring Security Config Class
* <b>History:</b>
* @author ์ฃผ๋ํ๋
* @version 1.0.0, 2022.06.14 ์ต์ด ์์ฑ
*/
@Slf4j
@Configuration @EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* Spring Security ์ค์ Method
* @param http - ์ธ๋ถ ๋ณด์ ๊ธฐ๋ฅ ์ค์ API ์ ๊ณต ๊ฐ์ฒด
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests() // Client๊ฐ http ๋ฐฉ์์ผ๋ก ์์ฒญ์ ๋ณด๋ด๋ฉด
.anyRequest().authenticated() // ๋ชจ๋ ์์ฒญ์ ๋ํด ์ธ์ฆ ๊ฒ์ฌ๋ฅผ ์ํํ๋ค.
.and() // ๊ทธ๋ฆฌ๊ณ ,
.formLogin() // ์ธ์ฆ ๋ฐฉ์์ formLogin ๋ฐฉ์
} // configure(HttpSecurity http) ๋
} // class ๋
์ต์ด ์์ ๊ฐ์ด ์ค์ ์ ํด ์ฃผ์๊ณ , Client๊ฐ http ๋ฐฉ์์ผ๋ก ์์ฒญ์ ๋ณด๋ด๋ฉด ๋ชจ๋ ์์ฒญ์ ๋ํด ์ธ์ฆ ํ์ธ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ , ์ธ์ฆ ๋ฐฉ์์ FormLogin ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๋๋ก ์ค์ ํ์์ด์.
๐ฆ ์ธ์ฆ API - Form ์ธ์ฆ
Form ์ธ์ฆ ๋ฐฉ์์ Login Logic์ ์๋์ ๊ฐ์ด ์ฒ๋ฆฌ๊ฐ ๋์.
http.formLogin() // Form Login ์ธ์ฆ ๊ธฐ๋ฅ On
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage("/signin") // ๊ฐ๋ฐ์ ์ ์ Login Page URI
.defaultSuccessUrl("/home") // Login ์ฑ๊ณต ๋ค ์ด๋ํ๊ฒ ๋ Page URI
.failureUrl("/login.html?error=true") // Login ์คํจ ๋ค ์ด๋ํ๊ฒ ๋ Page URI
.usernameParameter("username") // ์ด์ฉ์ ID ๋ณ์๋ช
์ค์
.passwordParameter("password") // ์ด์ฉ์ ๋น๋ฐ๋ฒํธ ๋ณ์๋ช
์ค์
.loginProcessingUrl("/signin") // Login Form Action URI
.successHandler(loginSuccessHandler()) // Login ์ฑ๊ณต ๋ค ํธ์ถ ๋ Handler
.failureHandler(loginFailureHandler()) // Login ์คํจ ๋ค ํธ์ถ ๋ Handler
}
๐ฆ ์ธ์ฆ API - UsernamePasswordAuthenticationFilter
๐ฆ ์ธ์ฆ API - Logout
์ด์ฉ์๊ฐ Logout ์์ฒญ์ ๋ณด๋ด๊ฒ ๋๋ฉด Spring Security ๋ด์์๋ ์ด๋ค ์ผ์ด ๋ฐ์ํ๊ฒ ๋ ๊น์?
์์ ๊ทธ๋ฆผ์์ ๋์ ์ ๋ฏ Session์ ๋ฌดํจํํ๊ณ , ์ธ์ฆ ํ ํฐ(์ด์ฉ์๊ฐ ์ธ์ฆ์ ํ์ ๋, ์์ฑ๋ ์ธ์ฆ ๊ฐ์ฒด)์ ์ญ์ ํ๊ฒ ๋ฉ๋๋ค. ์ด ๋, ์ธ์ฆ ํ ํฐ์ด ์ ์ฅ๋์ด ์๋ ๊ฐ์ฒด์ธ Security Context๋ฅผ ํจ๊ป ์ญ์ ํ๊ฒ ๋์.
๊ทธ๋ฆฌ๊ณ , ์ญ์ ํด์ผ ํ ์ฟ ํค ์ ๋ณด๊ฐ ์๋ค๋ฉด ํด๋น ์ฟ ํค๋ฅผ ์ญ์ ํ๊ณ , ๋ค์ Login Page๋ก ์ด๋ํ ์ ์๊ฒ ํด ์ฃผ๋ ๊ฒ์ด์์.
Spring Secutiry Config Class์์ http.logout()์ ์ค์ ํ๊ฒ ๋๋ฉด Logout ๊ธฐ๋ฅ์ ํ์ฑํ ํ ์ ์์ด์.
protected void configure(HttpSecurity http) throws Exception {
http.logout() // Logout ์ฒ๋ฆฌ
.logoutUrl("/logout") // Logout ์ฒ๋ฆฌ URI
.logoutSuccessUrl("/signin") // Logout ์ฑ๊ณต ๋ค ์ด๋ํ Page URI
.deleteCookies(" JSEESIONID", " remember-me " ) // Logout ๋ค Cookie ์ญ์ (๋ฐ๊ธ ๋ Cookie ๋ช
๊ธฐ์ฌ)
.addLogoutHandler(logoutHandler()) // Logout Handler(Logout ์ด ํ ํ๊ณ ์ ํ๋ ์์
์ด ์๋ค๋ฉด Customํ๊ฒ ์ฒ๋ฆฌํ๊ธฐ ์ํด ํธ์ถ)
.logoutSuccessHandler(logoutSuccessHandler()) // Logout ์ฑ๊ณต ๋ค Handler
}
์ฐธ๊ณ ๋ก Spring Security๋ ๊ธฐ๋ณธ์ ์ผ๋ก Logout์ ์ฒ๋ฆฌํ ๋, Post ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌ๋ฅผ ํ๋ต๋๋ค.
Get ๋ฐฉ์์ผ๋ก๋ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ์ง๋ง, ๊ธฐ๋ณธ์ ์ผ๋ก๋ Post ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๋ค๋ ๊ฒ์ ์์๋๋ฉด ์ข์ ๊ฑฐ ๊ฐ์์.
์ต์ด ์์ ๊ฐ์ด Login ์ ๋ณด๋ฅผ ์
๋ ฅํ๊ณ , Sign in ๋จ์ถ๋ฅผ ๋๋ฌ์ฃผ์์ด์.
Logout ์ฒ๋ฆฌ๋ฅผ ์ํด URI์ logout์ ์ ๋ ฅํด ์ค๋๋ค.
์ด Page๋ Spring Security๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ Page์
๋๋ค.
๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ํตํด ํ์ธ ํด๋ณด๋ฉด Post ๋ฐฉ์์ ์ด์ฉํด์ logout ์ฒ๋ฆฌ๋ฅผ ํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ ๊ฒ์ด์์.
Debug Mode๋ก ํ์ธ ํด ๋ณด๋ฉด Logout Button์ ๋๋ ์ ๋, Session์ ๋ฌดํจํ ํ๋ ๋ถ๋ถ์ ์ง์
ํ๋ ๊ฒ์ ํ์ธํ ์ ์์ด์.
๊ทธ๋ฐ ๋ค Success Handler๋ฅผ ํตํด ๋ค์ Sign in Page๋ก ์ด๋ ์ํค๋ ๊ฒ์ ํ์ธ ํ ์ ์์ด์.
๐ฆ ์ธ์ฆ API - LogoutFilter
์ด๋ฒ์๋ Logout Filter์ ๋ํด์ ๊ณต๋ถํด ๋ณผ๊ฒ์.
์ต์ด ์ด์ฉ์๊ฐ Logout์ ์์ฒญ(Post ๋ฐฉ์)ํ๊ฒ ๋๋ฉด LogoutFilter๊ฐ ๋ฐ์์ ์ฒ๋ฆฌํ๊ฒ ๋์.
๊ทธ๋ฌ๋ฉด AntPathRequestMatcher๊ฐ ์์ฒญ URI๊ฐ Logout ์ฒ๋ฆฌ๋ฅผ ์ํ URI์ธ์ง ๊ฒ์ฌ๋ฅผ ํ๊ฒ ๋์.
๋ง์ฝ URI๊ฐ ์ผ์นํ์ง ์๋๋ค๋ฉด doFilter๊ฐ ๋ฐ์ ๋ค์ Filter๋ก ์ด๋ํ๊ฒ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ , ์ผ์นํ๊ฒ ๋๋ฉด
Authentication์ด ํธ์ถ๋์ด SecurityContext (ํ์ฌ ์ด์ฉ์์ ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ๊ฐ์ฒด)๋ก ๋ถํฐ ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ๊บผ๋ด ๋ฐ์ SecutiryContextLogoutHandler ์ฆ, LogoutHandler์๊ฒ ์ ๋ฌ์ ํ๊ฒ ๋๋ ๊ฒ์ด์์. ํด๋น Handler๋ Session์ ๋ฌดํจํํ๊ณ , Cookie๋ฅผ ์ญ์ ํ๊ณ , SecurityContextHolder.clearContext()์์ SecutiryContext ๊ฐ์ฒด๋ฅผ ์ญ์ ํ๊ฒ ๋๋ ๊ฒ์ด์์. ๊ทธ๋ฆฌ๊ณ , ์ธ์ฆ ๊ฐ์ฒด๋ null๋ก ์ด๊ธฐํ ํ๋ ๊ฒ์ด์์.
๋ง์ฝ Post๊ฐ ์๋ Get ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์ ํ ๋๋ SecurityContextLogoutHandler๋ฅผ ํตํด ์ฒ๋ฆฌ๋ฅผ ํ ์ ์์ด์.
์์ ์์
์ด ์๋ฃ๊ฐ ๋๋ฉด LogoutFilter๋ SimpleUrlLogoutSuccessHandler๋ฅผ ํธ์ถํด์ Sign in Page๋ก ์ด๋ํ๊ฒ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ ๊ฒ์ด์์.
๐ฆ ์ธ์ฆ API - Remember Me ์ธ์ฆ
์์ ๊ฐ์ด Remember Me ๊ธฐ๋ฅ์ ์ด์ฉํ๊ฒ ๋๋ฉด ์ด๋ค์ผ์ด ๋ฒ์ด์ง๊น์?
์์ ๊ธฐ๋ฅ์ Session์ด ๋ง๋ฃ๋๊ณ , ์น ๋ธ๋ผ์ฐ์ ๊ฐ ์ข
๋ฃ๋ ๋ค์๋ Application์ด ์ด์ฉ์๋ฅผ ๊ธฐ์ตํ๊ฒ ํ๋ ๊ธฐ๋ฅ์ด์์.
์ฆ, ์๋ Login ๊ธฐ๋ฅ๊ณผ ์ ์ฌํ ๊ธฐ๋ฅ์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ ๊ฒ์ด์์.
Remember-Me Cookie์ ๋ํ Http Request๋ฅผ ํ์ธํ๊ณ , Token ๊ธฐ๋ฐ ์ธ์ฆ์ ์ด์ฉํด ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํ๊ณ , Token์ด ๊ฒ์ฆ๊ดด๊ฒ ๋๋ฉด ์ด์ฉ์๋ Login์ ํ ์ ์์ด์.
์ด์ฉ์์ Life Cycle์ ์๋์ ๊ฐ์์.
• ์ธ์ฆ ์ฑ๊ณต ( Remember-Me Cookie ์ค์ )
• ์ธ์ฆ ์คํจ ( Cookie ์กด์ฌ ์ Cookie ๋ฌดํจํ)
• Logout ( Cookie ์กด์ฌ ์ Cookie ๋ฌดํจํ)
Spring Secutiry Config Class์์ http.rememberMe()์ ์ค์ ํ๊ฒ ๋๋ฉด RememberMe ๊ธฐ๋ฅ์ ํ์ฑํํ ์ ์์ด์.
protected void configure(HttpSecurity http) throws Exception {
http.rememberMe()
.rememberMeParameter("remember") // ๊ธฐ๋ณธ ๋งค๊ฐ๋ณ์ ๋ช
์ remember-me
.tokenValiditySeconds(3600) // ๊ธฐ๋ณธ๊ฐ์ 14์ผ
.alwaysRemember(true) // Remember Me ๊ธฐ๋ฅ์ด ํ์ฑํ ๋์ง ์์๋ ํญ์ ์คํ false๋ฅผ ๊ถ๊ณ
.userDetailsService(userDetailsService)
}
์ต์ด userDetailsService๋ฅผ ์ด์ฉํ๊ธฐ ์ํด @RequiredArgsConstructor Lombok์ ์ด์ฉํ์ฌ final member ๋ณ์ UserDetailsService๋ฅผ ์ฃผ์
ํด ์ฃผ์์ด์.
๊ฐ์์์๋ @Autowired๋ฅผ ํตํด UserDetailsService๋ฅผ ์ฃผ์
ํ๋๋ฐ, Member ๋ณ์์ ๋ํ ์ฝ์
์ ๊ถ๊ณ ์ฌํญ์ด ์๋๋ฏ๋ก ์์ ๊ฐ์ด ์์ฑ์ ์ฃผ์
์ ํ ์ ์๊ฒ ๋ณ๊ฒฝ ํด ์ฃผ์์ด์.
๊ทธ๋ฐ ๋ค Logout ์ค์ ๋ฐ์ ์์ ๊ฐ์ด Remember Me ๊ด๋ จ ์ค์ ์ ํด ์ฃผ์์ด์.
Server๋ฅผ ์ฌ ๊ตฌ๋ํ๊ณ , ๋ค์ Root Page์ ์ ๊ทผ์ ํ๋ฉด Login Page๋ก ์ด๋ํ๊ฒ ๋๊ณ , ์์ ๊ฐ์ด Remember Me์ ๊ด๋ จํ Check Box๊ฐ ์๊ธด๊ฑธ ํ์ธํ ์ ์์ด์.
Remember Me Check Box์ Check๋ฅผ ํ๊ณ Login์ ํด ๋ณผ๊ฒ์.
์ด๋ ๊ฒ ์ธ์ฆ์ด ๋์์ด์.
์ธ์ฆ์ด ๋์๋ค๋ ๊ฒ์ Spring Security์์ ์ด์ฉ์ Session์ด ๋ง๋ค์ด ์ก๋ค๋ ๊ฒ์ด๊ณ , ํด๋น Session์ด ์ฑ๊ณตํ ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ๋ด๊ณ ์๋ ๊ฒ์ด์์.
๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ํตํด Cookie๋ฅผ ํ์ธํด ๋ณด๋ ์์ ๊ฐ์ด ๊ฐ์ด ๋ด๊ฒจ ์๋ ๊ฒ์ ํ์ธํ ์ ์์ด์.
ํด๋น Page๋ฅผ ์ข
๋ฃํ๋ค๊ฐ ๋ค์ ์ ๊ทผ์ ํ๊ฒ ๋๋ฉด ๋ฐ๋ก ์ ์์ด ๊ฐ๋ฅํ ๊ฑธ ํ์ธํ ์ ์์ด์.
์ด๋ ์์ ๊ฐ๋ฐ์ ๋๊ตฌ์์ ๋ณด์๋ฏ์ด Client๊ฐ Server๊ฐ ์ค JSessionID ๊ฐ์ ๊ฐ์ง๊ณ ์์๊ณ , ์ด๋ฅผ ๋ค์ ์ง์
ํ ๋, Server์๊ฒ ๋๊ฒจ ์ธ์ฆ์ ํต๊ณผํ๊ธฐ ๋๋ฌธ์ด์์.
๊ทธ๋ผ ํฌ๋กฌ ํ์ฅ ํ๋ก๊ทธ๋จ ์ค EditThisCookie๋ฅผ ํตํด Cookie๋ฅผ ํ์ธํด ๋ณผ๊ฒ์.
์ด๋ ๊ฒ Cookie ์ ๋ณด๋ฅผ ๊ฐ๋ฐ์ ๋๊ตฌ ๋ณด๋ค ๋ ๊ฐํธํ๊ฒ ํ์ธํ ์ ์์ด์.
์ด ๊ณณ์์ ํด์งํต ๋ชจ์์ ๋๋ฌ Cookie๋ฅผ ํ๋ฒ ๋ ๋ ค ๋ณผ๊ฒ์!
์ด๋ค ์ผ์ด ๋ฐ์ํ ๊น์?
Remember-Me๋ ์ ์ธํ๊ณ , JSessionID๋ฅผ ์ง์ฐ๊ณ ๋์ ๋ค์ ์ ์์ ํ๊ฒ ๋๋ฉด ๋ง์ฐฌ๊ฐ์ง๋ก ์ธ์ฆ ์ ์ฐจ ์์ด ์ ์์ ํ๋ ๊ฒ์ ํ์ธํ ์ ์์ด์.
๋ค์ Cookie๋ฅผ ํ์ธํด๋ณด๋ฉด JSessionID๋ ๋ค์ ๋ฐ์์จ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
์ด๋ฒ์๋ ๋ ๋ค ํ๋ฒ ์ง์๋ณผ๊ฒ์.
๋ชจ๋ Cookie๋ฅผ ๋ค ๋ ๋ ธ๊ณ , ์๋ก๊ณ ์นจ์ ํด ๋ณผ๊ฒ์.
๊ทธ๋ผ Server๋ '์ฒ์ ๋ต๊ฒ ์ต๋๋ค!'๋ฅผ ํ๋ฉด์ ๋๊ตฌ์ธ์ง๋ฅผ ๋ฌผ์ด๋ณด๋ ๊ฒ์ด์์.
๐ฆ ์ธ์ฆ API - RememberMeAuthenticationFilter
์ต์ด RememberMeAuthenticationFilter๊ฐ ์ด์ฉ์์ ์์ฒญ์ ๋ฐ๊ฒ ๋๋ฉด ์ด๋ค ์ผ์ด ์ผ์ด๋ ๊น์?
์ฒซ๋ฒ์งธ๋ ๋ฐ๋ก Authentication ์ฆ, ์ธ์ฆ ๊ฐ์ฒด๊ฐ Null์ผ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ, ์ธ์ฆ ๊ฐ์ฒด๋ ์์์๋ ์ธ๊ธํ์ง๋ง, SecurityContext์ ์ ์ฅ์ด ๋์ด ์์ด์. ์ฆ, ์ด์ฉ์๊ฐ ์ธ์ฆ์ ํ๊ฒ ๋๋ฉด ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ฒ ๋๊ณ , ์ด ์ธ์ฆ ๊ฐ์ฒด๋ฅผ SecurityContext์ ๋ด๊ฒ ๋๋ ๊ฒ์ด์์. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ด์ฉ์๊ฐ ์ธ์ฆ์ ํ์๋ค๋ ๊ฒ์ ๋ฐ๋ก Authentication์ด Null์ด ์๋๋ผ๋ ๊ฒ์ด์์.
๋ง์ฝ ์ด์ฉ์์ Session์ด ๋ง๋ฃ๋์๊ฑฐ๋, Session์ด ์ด๋ ํ ์ด์ ๋ก ๋๊ฒจ์ ธ์ ๋ ์ด์ Session ์์์ SecurityContext๋ฅผ ์ฐพ์ง ๋ชปํ๊ณ , SecurityContext๊ฐ ์กด์ฌํ์ง ์์ผ๋ฏ๋ก, SecurityContext ์์ Authentication ๊ฐ์ฒด๋ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ๋ก ์ฒซ๋ฒ์งธ ๊ฒฝ์ฐ์์. ์ด ๋ ๋ฐ๋ก RememberMeAuthenticationFilter๊ฐ ๋์ํ๊ฒ ๋๋ ๊ฒ์ด์์.
๋ง์ฝ Authentication์ด Null์ด ์๋๋ผ๋ฉด RememberMeAuthenticationFilter๋ ๋์ํ์ง ์๋๋ฐ, ๊ทธ ์ด์ ๋ ์ด๋ฏธ ์ธ์ฆ ๊ฐ์ฒด๊ฐ ์๋ค๋ ์ด์ผ๊ธฐ์ด๊ธฐ ๋๋ฌธ์ ๋ค์ ์ธ์ฆ์ ๋ฐ์ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ด์์.
์ฆ, RememberMeAuthenticationFilter๊ฐ ๋์ํ๋ค๋ ๊ฒ์ ์ธ์ฆ ์ฒ๋ฆฌ๋ฅผ ์ํด ๋์ํ๋ค๊ณ ๋ณด๋ฉด ๋๋ ๊ฒ์ด์์.
๋๋ฒ์งธ๋ ์ด์ฉ์๊ฐ Form ์ธ์ฆ์ ๋ฐ์ ๋น์ Remember Me ๊ธฐ๋ฅ์ ํ์ฑํํ ๋ค ์ธ์ฆ์ ํ ๋ค Server๋ก ๋ถํฐ Remember Me Cookie๋ฅผ ๋ฐ๊ธ ๋ฐ์ ๊ฒฝ์ฐ์ ๋์ํ๋ ๊ฒ์ด์์.
์์ ๊ฒฝ์ฐ ์ด์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ข
๋ฃํ๊ฑฐ๋ ํ์ ์ ์ด์ฉ์์ Session์ ๋ฌดํจํ๋๋, ๋ค์ Server์ ์ ๊ทผํ ๋, Request Header์ Remember Me Cookie ๊ฐ์ ๊ฐ์ง๊ณ , ์ ๊ทผํ๊ฒ ๋๋ฉด ํด๋น Cookie๋ฅผ ์ด์ฉํ์ฌ ์ธ์ฆ์ ์๋ํ๊ฒ ๋๋ต๋๋ค.
RememberMeAuthenticationFilter๊ฐ ๋์ํ๊ฒ ๋๋ฉด RememberMeServies๊ฐ ํธ์ถ ๋๊ฒ ๋๋๋ฐ, ์ด ์น๊ตฌ๋ ๋ ๊ฐ์ ๊ตฌํ์ฒด๋ฅผ ๋ณด์ ํ๊ณ ์๋ ์น๊ตฌ์์. ๋ฐ๋ก TokenBasedRememberMeServices์ PersistentTokenBasedRememberMeServices์์. ์ด ๋ ์น๊ตฌ๊ฐ ๋ฐ๋ก Remember Me ์ธ์ฆ ์ฒ๋ฆฌ๋ฅผ ํ๋ ์น๊ตฌ๋ค์ด์์.
TokenBasedRememberMeServices๋ Memory์ ์ ์ฅ๋ Token๊ณผ ์ด์ฉ์๊ฐ ์์ฒญ์ ๋ณด๋์ ์ ๋ณด๋ธ Cookie์์ ์๋ Token๊ณผ ๋น๊ตํด์ ์ธ์ฆ์ฒ๋ฆฌ๋ฅผ ํ๋ ์น๊ตฌ์์.
๊ธฐ๋ณธ์ ์ผ๋ก ์ด Token์ 14์ผ์ด๋ผ๋ ๊ธฐ๊ฐ ๋ง๋ฃ๊ฐ ์ ํด์ ธ ์์ด์.
PersistentTokenBasedRememberMeServices๋ Persistent ์ฆ, ์๊ตฌ์ ์ผ๋ก ์ด์ฉํ๋ ๋ฐฉ์์ธ๋ฐ, DB์ Token๊ฐ์ ์ ์ฅํ๊ณ , ์ด์ฉ์๊ฐ ์์ฒญ์ ๋ณด๋์ ์ ๋ณด๋ธ Cookie์์ ์๋ Token๊ณผ ๋น๊ตํด์ ์ธ์ฆ์ฒ๋ฆฌ๋ฅผ ํ๋ ์น๊ตฌ์์.
์ด์ Remember Me Token Cookie๋ฅผ ์ถ์ถํ๊ฒ ๋๊ณ , Token์ด ์กด์ฌํ์ง ์์ผ๋ฉด doFilter๋ฅผ ํตํด ๋ค์ Filter๊ฐ ๋์ํ๊ฒ ์ฒ๋ฆฌ๊ฐ ๋๊ณ , Token์ด ์๋ค๋ฉด Remember Me Token์ ๋๋ฆ์ ๊ท์น๋ค์ด ์๋๋ฐ, ์ด ๊ท์น๋ค์ด ์ ์ง์ผ์ ธ์ ์๋์ง๋ ํ์ธํ๊ฒ ๋์. ๋ง์ฝ ์๋๋ผ๋ฉด Exception์ด ํฐ์ง๊ฒ ๋๊ณ , ์ ์ง์ผ์ ธ์ ์๋ค๋ฉด ์ ์ฅ๋์ด ์๋ Token๊ณผ ์ด์ฉ์๊ฐ ๋ณด๋ธ Token์ด ์ผ์นํ๋์ง ํ์ธ์ ํฉ๋๋ค.
์ผ์นํ์ง ์์ผ๋ฉด ์ญ์ Exception์ด ํฐ์ง๊ฒ ๋๊ณ , ์ผ์นํ๋ฉด ํด๋น ์ด์ฉ์ ๊ณ์ ์ด DB์ ์กด์ฌํ๋์ง ํ์ธ์ ํ๊ณ , ์กด์ฌํ๋ค๋ฉด ์๋ก์ด Authentication ๊ฐ์ฒด๋ฅผ ์์ฑํด์ AuthenticationManager์๊ฒ ์ ๋ฌํ์ฌ ์ธ์ฆ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด์์.
์ญ์ ์ด์ฉ์๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด Exception์ด ํฐ์ง๋ต๋๋ค.
Remember Me Token์๋ ์ด์ฉ์์ Password ์ ๋ณด, ID ์ ๋ณด, Token ๋ง๋ฃ์ผ ์ ๋ณด ๋ฑ์ด ๋ด๊ฒจ ์์ด์.
๐ฆ ์ธ์ฆ API - AnonymousAuthenticationFilter
AnonymousAuthenticationFilter๋ ์๋์ ๊ฐ์ด ๋์ํ๋ ์น๊ตฌ์์.
• ์ต๋ช
์ด์ฉ์ ์ธ์ฆ ์ฒ๋ฆฌ Filter.
• ์ต๋ช
์ด์ฉ์์ ์ธ์ฆ ์ด์ฉ์๋ฅผ ๊ตฌ๋ถํด์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ฉ๋๋ก ์ฌ์ฉ.
• ํ๋ฉด์์ ์ธ์ฆ ์ฌ๋ถ ๊ตฌํ ์ isAnonymous()์ isAuthenticated()๋ก ๊ตฌ๋ถํด์ ์ฌ์ฉ.
• ์ธ์ฆ ๊ฐ์ฒด๋ฅผ Session์ ์ ์ฅํ์ง ์์.
์๋ ์ด์ฉ์๊ฐ ์ธ์ฆ์ ํ๊ฒ ๋๋ฉด ์ธ์ฆ ๊ฐ์ฒด์ ํด๋น ์ด์ฉ์์ ์ ๋ณด๋ฅผ ๋ด๊ฒ ๋๊ณ , ์ด๋ฅผ Session์ผ๋ก ๊ฐ์ง๊ณ ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ, ์ธ์ฆ์ ๋ฐ์ง ์๊ฒ ๋๋ฉด ์ธ์ฆ ๊ฐ์ฒด ๊ฐ์ ๋น์ฐํ Null์ด ๋ ๊ฑฐ์์.
ํ์ง๋ง, AnonymousAuthenticationFilter๋ ์ธ์ฆ ๋ฐ์ง ์์ ์ด์ฉ์์ ๋ํ ์ธ์ฆ ๊ฐ์ฒด๋ฅผ Null๋ก ๋๋ ๊ฒ์ด ์๋๊ณ , ๋ณ๋ ์ต๋ช
์ด์ฉ์์ฉ ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ด์ฉํ๋ ๊ฒ์ด์์.
์ต์ด ์ด์ฉ์๊ฐ ์์ฒญ์ ๋ณด๋ด๊ฒ ๋๋ฉด AnonymousAuthenticationFilter๊ฐ ์์ฒญ์ ๋ฐ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ฉด ํ์ฌ ์์ฒญ์ ๋ณด๋ธ ์ด์ฉ์๊ฐ ์ธ์ฆ ๊ฐ์ฒด๊ฐ ์กด์ฌํ๋์ง ์ฌ๋ถ๋ฅผ ๋จผ์ ํ๋จํ๊ฒ ๋ฉ๋๋ค.
์ธ์ฆ์ ๋ฐ์๋ค๋ฉด SecurityContext์ ํด๋น ์ด์ฉ์์ ์ธ์ฆ ๊ฐ์ฒด๊ฐ ์ ์ฅ์ด ๋์ด ์์ ๊ฒ์ด์์.
SecurityContext ์์ ์ธ์ฆ ๊ฐ์ฒด๊ฐ ์๋ค๋ ๊ฒ์ ํด๋น ์ด์ฉ์๋ ์ธ์ฆ์ ๋ฐ์ง ์์๋ค๊ณ ํ๋จํ ์ ์์ด์.
๋ง์ฝ ์ธ์ฆ ๊ฐ์ฒด๊ฐ ์กด์ฌํ๋ค๋ฉด AnonymousAuthenticationFilter๋ ๋ณ๋ค๋ฅธ ์์
์์ด doFilter๋ฅผ ํตํด ๋ค์ Filter๋ก ์์
์ ๋๊น๋๋ค.
์ธ์ฆ ๊ฐ์ฒด๊ฐ ์กด์ฌํ์ง ์๋๋ค๋ฉด ์ต๋ช
์ด์ฉ์๋ก ํ๋จํด์ AnonymousAuthenticationToken ์ฆ, ์ต๋ช
์ด์ฉ์์ฉ Token์ ์์ฑ์ ํด์ Null๋ก ์ฒ๋ฆฌํ์ง ์๋ ๊ฒ์ด์์.
๊ทธ๋ฐ ๋ค SecurityContextHolder ์์ SecurityContext์ ์ต๋ช
์ด์ฉ์์ฉ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋์ ์ธ์ฆ์ ๊ฑฐ์น์ง ์์์ง๋ง, ์ธ์ฆ์ ๋ฐ์์ ๋์ ๋์ผํ๊ฒ SecurityContext ์์ ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๋๋ก ์ฒ๋ฆฌ๋ฅผ ํ๋ ๊ฒ์ด์์.
isAnonymous() ๊ฐ์ด True์ผ ๋ ์ต๋ช
์ด์ฉ์๋ผ๋ ๊ฒ์ด ํ์ธ๋๊ธฐ ๋๋ฌธ์ Menu๋ฅผ ๊ตฌ์ฑํ ๋, Login Page๋ก ์ด๋ํ๊ฒ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๊ณ ,
isAuthenticated() ๊ฐ์ด True๋ผ๋ ๊ฒ์ ์ธ์ฆ์ ๋ฐ์ ์ด์ฉ์๋ผ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ Menu๋ฅผ ๊ตฌ์ฑํ ๋, Logout Button๊ณผ ๊ธฐ๋ฅ์ด ํ์ฑํ ๋๋๋ก ์ฒ๋ฆฌํ ์ ์๋ ๊ฒ์ด์์.
๐ฆ ์ธ์ฆ API - ๋์ Session Controll / Session ๊ณ ์ ๋ณดํธ / Session ์ ์ฑ
๋์ Session ์ ์ด๋ ๋ฌด์์ผ๊น์? ํ๋์ ๊ณ์ ์ผ๋ก ์ฌ๋ฌ๊ฐ์ ์ธ์ฆ์ ๋ฐ์ ๋, ์์ฑ ๋ Session์ ๊ฐ์๊ฐ ์ด๊ณผ๋์์ ๋, ์ด๋ค์์ผ๋ก ์ด๋ฐ Session์ ์ ์ดํ ๊ฒ์ธ์ง๋ฅผ ์ ํ๋ ๋ถ๋ถ ์
๋๋ค.
Spring Security๋ ์ด๋ด ๋, ๋ ๊ฐ์ง๋ก Handling์ด ๊ฐ๋ฅํ๋๋ก ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ณ ์์ต๋๋ค.
์ต์ด ์ต๋ Session ํ์ฉ ๊ฐ์๊ฐ ์ด๊ณผํ๋ค๊ณ ๊ฐ์ ์ ํด ๋ณผ๊ฒ์. ์ด ๋, ํ๋์ ๊ณ์ ์ผ๋ก ์์ฑ๋ ์ ์๋ Session์ ์ต๋ ๊ฐ์๋ ํ๋๋ผ๊ณ ๊ฐ์ ์ ํด ๋ณผ๊ฒ์.
์ด ๋, ์ด์ ์ด์ฉ์ Session์ ๋ง๋ฃ ์ํค๋ ์ ๋ต์ ํ๋ฒ ์ดํด ๋ณผ๊ฒ์.
์ต์ด ์ด์ฉ์ 1์ด Server์ Login์ ํ๊ณ , Server๋ ํด๋น ์ด์ฉ์์๊ฒ Session์ ์์ฑํด์ ์ ๋ฌํด ์ค๋๋ค.
๊ทธ๋ ๋ค๋ฉด Server์๋ ์ด์ฉ์ 1์ ๋ํ Session์ด ์์ฑ๋์ด ์์ ๊ฑฐ์์.
๊ทธ๋ฐ ๋ค ์ด์ฉ์ 2๊ฐ Login์ ์์ฒญ์ ํด์. ๋น์ฐํ ์ด์ฉ์ 1์ด ์ด์ฉํ๋ ๊ณ์ ์ ๋ณด๋ฅผ ๋์ผํ๊ฒ ์ด์ฉํ์ฌ Login์ ํ๋ ๊ฒ์ด์์.
๊ทธ๋ฌ๋ฉด ์ด์ฉ์ 2์ ๋ํ Session์ด ์๋กญ๊ฒ ๋ง๋ค์ด์ ธ์ ๋ฐ๊ธ๋ฉ๋๋ค.
Server์๋ ์ด์ฉ์ 1๊ณผ ์ด์ฉ์ 2์ ๋ํ Session์ด ์ ์ฅ๋์ด ์๊ฒ ๋ค์.
๊ทธ๋ ๋ค๋ผ๋ ๊ฑด Server์๋ ๋์ผํ ๊ณ์ ์ ๋ํ Session์ด ๋ ๊ฐ๊ฐ ์์ฑ๋์๋ค๋ ๊ฒ์ด์์.
์์์ ์์๋ ์ต๋ Session ํ์ฉ ๊ฐ์๊ฐ 1๊ฐ๋ผ๊ณ ํ์ด์.
๊ทธ๋ผ ์ด๊ณผ๊ฐ ๋ ๊ฒ์ด๊ณ , ์ด ๋, Server๋ ์ด ์ Login ์ธ์ฆ์ ๋ํ Session ๋ง๋ฃ๊ฐ ๋๋๋ก ์ค์ ํ๊ฒ ๋๋ฉด
Server๋ ์ด ์ ์ด์ฉ์์ธ ์ด์ฉ์ 1์ ๋ํ Session์ ์ฆ์ ๋ง๋ฃ ์์ผ ๋ฒ๋ ค์.
์ด ๋ฐฉ์์ด ๋ฐ๋ก ๋์ Session ์ ์ด์์ ์ด์ ์ด์ฉ์ Session์ ๋ง๋ฃ ์ํค๋ ์ ๋ต์ด์์.
๋๋ฒ์งธ๋ ํ์ฌ ์ด์ฉ์ ์ธ์ฆ์ ์คํจํ๋๋ก ํ๋ ์ ๋ต์ด์์.
์ต์ด ์ด์ฉ์ 1์ด Login์ ์๋ํด์ Server๋ Session์ ์์ฑํ๊ณ , ๋ฐ๊ธ์ ํด ์ค๋๋ค.
๊ทธ๋ฐ ๋ค ์ด์ฉ์ 2๊ฐ ๋์ผ ๊ณ์ ์ผ๋ก Login์ ์๋ํ๊ฒ ๋๋ฉด ์ธ์ฆ ์์ธ๋ฅผ ๋ฐ์์์ผ Login์ด ๋ถ๊ฐ๋ฅํ๊ฒ ์ฒ๋ฆฌํด ๋ฒ๋ฆฌ๋ ์ ๋ต์ด์์.
์ฒซ๋ฒ์งธ๋ ์ฒซ๋ฒ์งธ ์ด์ฉ์์ ๋ํ Session์ ๋ง๋ฃ ์ํค๊ณ , ๋๋ฒ์งธ๋ ๋๋ฒ์งธ ์ด์ฉ์์ ๋ํด ์ธ์ฆ์ ํ์ง ๋ชปํ๋๋ก ๋ง๋ ์ ๋ต์ด์์.
๋์ Session ์ ์ด๋ http.sessionManagement()๋ฅผ ํตํด ๊ตฌํํ๋๋ฐ, ์ด๋ Session ๊ด๋ฆฌ ๊ธฐ๋ฅ์ด ์๋ํ๊ฒ ํ๋ ๋ถ๋ถ์
๋๋ค.
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.maximumSessions(1) // ์ต๋ ํ์ฉ ๊ฐ๋ฅ Session ์ ์ง์ ( -1์ ๋ฌด์ ํ Session ํ์ฉ)
.maxSessionsPreventsLogin(true) // ๋์ Login ์ฐจ๋จ(์ด์ ์ด์ฉ์ Session์ ๋ง๋ฃ ์ํค๋ ์ ๋ต), flase์ผ ๊ฒฝ์ฐ ๊ธฐ์กด Session ๋ง๋ฃ๋ก ๋์(Default) ์ด์ฉ์ ์ธ์ฆ์ ์คํจํ๋๋ก ํ๋ ์ ๋ต
.invalidSessionUrl("/invalid") // Session์ด ์ ํจํ์ง ์์ ๋, ์ด๋ํ Page ์ง์
.expiredUrl("/expired") // Session์ด ๋ง๋ฃ๋์์ ๊ฒฝ์ฐ ์ด๋ํ Page ์ง์
์ด๋ฒ์๋ ์ธ์
๊ณ ์ ๋ณดํธ์ ๋ํด ๊ณต๋ถ ํด ๋ณผ๊ฒ์.
์์ ๊ทธ๋ฆผ์ ๋ํด ํ๋ํ๋ ์ดํด ๋ณผ๊ฒ์.
์ต์ด ๊ณต๊ฒฉ์๊ฐ Server์ ์ ์์ ํฉ๋๋ค.
๊ทธ๋ฌ๋ฉด Server๋ ๊ณต๊ฒฉ์์๊ฒ JSessionID๊ฐ ๋ด๊ธด Cookie๋ฅผ ๋ฐ๊ธํด ์ค๋๋ค.
๊ทธ๋ฐ ๋ค์ ๊ณต๊ฒฉ์๋ ์์ ์ด Server์๊ฒ ๋ฐ์ JSessionID ๊ฐ์ ์ค๋ํ ์ด์ฉ์์๊ฒ ์ฌ์ด ๋๋ ์์
์ ํฉ๋๋ค.
๊ทธ๋ฐ ๋ค ์ด์ฉ์๋ ๊ณต๊ฒฉ์๊ฐ ์ฌ์ด๋์ JSessionID๋ฅผ ๊ฐ์ง๊ณ , Login์ ์๋ํ๊ฒ ๋ฉ๋๋ค.
Server๋ ์ ์์ ์ธ ์ด์ฉ์๋ผ ํ๋จํ๊ณ , Login ์ฒ๋ฆฌ๋ฅผ ํ ๊ฒ์ด์์.
์ด ๋๋ถํฐ ๊ณต๊ฒฉ์๋ ์์ฒญ๋ ์ผ์ ํด๋ผ ์ ์๊ฒ ๋๋๋ฐ, ๊ณต๊ฒฉ์์ ์ด์ฉ์์ JSessionID ๊ฐ์ด ๊ฐ๋ค๋ ๊ฑด ๊ณต๊ฒฉ์๋ ์ด์ฉ์์ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์๋ค๋ ๊ฒ์ด ๋ฉ๋๋ค.
์ฆ, ๊ณต๊ฒฉ์๋ ๋ฐ๋ก ์ธ์ฆ์ ๋ฐ์ง ์์๋ ์ด์ฉ์์ธ ์ฒ ์์ฅ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ด์์.
์ด ๊ณต๊ฒฉ ๊ธฐ๋ฒ์ด ๋ฐ๋ก Session ๊ณ ์ ๊ณต๊ฒฉ ๊ธฐ๋ฒ์ด์์.
์์ ๊ณต๊ฒฉ ๊ธฐ๋ฒ์ ๋ฐฉ์ดํ๊ธฐ ์ํด Spring Security๋ Session ๊ณ ์ ๋ณดํธ ๊ธฐ๋ฒ์ ๋ง๋ค์ด ๋จ์ด์.
๊ทธ๋ฐ ์ด๋ค ๋ฐฉ๋ฒ์ผ๋ก ์ด ๊ณต๊ฒฉ์ ๋ง์๋ด๋๋ก ๋ง๋ค์ด ๋จ์๊น์?
์ด์ฉ์๊ฐ ๊ณต๊ฒฉ์๊ฐ ์ฌ์ด๋์ JSessionID ๊ฐ์ ๊ฐ์ง๊ณ ์ธ์ฆ ์๋๋ฅผ ํ ๋, Server๊ฐ ์๋ก์ด Session์ ๋ฐ๊ธํ๊ณ , ์๋ก์ด Cookie๋ฅผ ๋ง๋ค์ด ์ฃผ๋ ๋ฐฉ๋ฒ์ผ๋ก ์ด ๊ณต๊ฒฉ์ ๋ง์๋ด๊ณ ์์ด์.
Session ๊ณ ์ ๋ณดํธ๋ http.sessionManagement()๋ฅผ ํตํด ํ์ฑํ ํ ์ ์์ด์. ์ด ์น๊ตฌ๋ฅผ ์ด์ฉํ๋ฉด Session ๊ด๋ฆฌ ๊ธฐ๋ฅ์ด ํ์ฑํ ๋๋ต๋๋ค.
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionFixation().changeSessionId() // Default Value -> non, migrateSession, new Session์ด ์กด์ฌ
}
changeSessionId() ๋ ์ด์ฉ์๊ฐ ์ธ์ฆ์ ์ฑ๊ณตํ๊ฒ ๋๋ฉด ํด๋น ์ด์ฉ์์ Session์ ๊ทธ๋๋ก ๋๊ณ , Session ID ๊ฐ๋ง ๋ณ๊ฒฝ์ ํฉ๋๋ค. ์ฐธ๊ณ ๋ก ์ด ์น๊ตฌ๋ ์๋ธ๋ฆฟ 3.1์์ ๊ธฐ๋ณธ๊ฐ์ด์์.
migrateSession()์ ๊ฒฝ์ฐ๋ Session๊ณผ Session ID๊ฐ ๋ชจ๋ ์๋กญ๊ฒ ๋ง๋ค์ด ์ง๋ ๊ฒ์ด์์. ๊ทธ๋ฆฌ๊ณ ์ด ์น๊ตฌ๋ ์๋ธ๋ฆฟ 3.1 ์ดํ์์ ๊ธฐ๋ณธ๊ฐ์ด์์.
์ ๋ ์น๊ตฌ๋ค์ ์๋กญ๊ฒ Session์ด ์์ฑ๋๊ธฐ ์ด ์ ์ ์ค์ ๋ ๊ฐ์ ๋ชจ๋ ๊ทธ๋๋ก ์ฌ์ฉํ๊ฒ ํ ์ ์๋ ์น๊ตฌ๋ค์ด์์.
newSession()์ ๊ฒฝ์ฐ Session๊ณผ JSessionID ๋ชจ๋ ์๋กญ๊ฒ ๋ฐ๊ธ๋๋ฉฐ, ์ด ์ ์ ์ค์ ๋ ๊ฐ ๋ชจ๋๋ฅผ ์ฌ์ฉํ์ง ๋ชปํ๊ณ , ์๋กญ๊ฒ ์ค์ ํด์ผ ํ๋ ์น๊ตฌ์์.
๋ง์ง๋ง์ผ๋ก none์ ์๋ฏธ๊ฐ ์์ด์. ์ด๋ ๊ฒ ํด ๋์ผ๋ฉด ์์ ๊ณต๊ฒฉ ๊ธฐ๋ฒ์ ๋นํ ์ ๋ฐ์ ์์ต๋๋ค.
์์ ๋ด์ฉ์ ์ฐ๋ฆฌ๊ฐ ์ค์ ์ ์ผ๋ก Coding์ ํ์ง ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋๋๊ฒ Spring Security๊ฐ ์๋ํ๊ณ ์์ด์.
์ด๋ฒ์๋ Session ์ ์ฑ
์ ๋ํด ๊ณต๋ถํด ๋ณผ๊ฒ์.
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy. If_Required)
}
• SessionCreationPolicy.Always : Spring Security๊ฐ ํญ์ Session ์์ฑ.
• SessionCreationPlicy.If_Required : Spring Security๊ฐ ํ์ ์ Session ์์ฑ (Default Value).
• SessionCreationPolicy.Never : Spring Security๊ฐ Session์ ์์ฑํ์ง ์์ง๋ง, ์ด๋ฏธ Session์ด ์กด์ฌํ๋ฉด ์ฌ์ฉ.
• SessionCreationPolicy.Stateless : Spring Security๊ฐ Session์ ์์ฑํ์ง ์๊ณ , Session์ด ์กด์ฌํด๋ ์ฌ์ฉํ์ง ์์. (Session ๋ฐฉ์์ ์ฌ์ฉํ์ง ์์ ๋ ์ฌ์ฉ)
๐ฆ ์ธ์ฆ API - SessionManagementFilter
1. Session ๊ด๋ฆฌ
• ์ธ์ฆ ์ ์ด์ฉ์์ Session ์ ๋ณด๋ฅผ ๋ฑ๋ก, ์กฐํ, ์ญ์ ๋ฑ Session ์ด๋ ฅ ๊ด๋ฆฌ.
2. ๋์์ Session ์ ์ด
• ๋์ผ ๊ณ์ ์ผ๋ก ์ ์์ด ํ์ฉ๋๋ ์ต๋ Session ์ ์ ํ.
3. Session ๊ณ ์ ๋ณดํธ
• ์ธ์ฆ ํ ๋๋ง๋ค Session Cookie๋ฅผ ์๋ก ๋ฐ๊ธํ์ฌ ๊ณต๊ฒฉ์์ Cookie ์กฐ์ ๋ฐฉ์ง.
4. Session ์์ฑ ์ ์ฑ
• Always, If_Required, Never, Stateless
๐ฆ ์ธ์ฆ API - ConcurrentSessionFilter
์ด ์น๊ตฌ๋ ์์ SessionManagementFilter์์ ๋์์ Session ์ ์ด๋ฅผ ํจ๊ป ์ฒ๋ฆฌํ๋ ์น๊ตฌ์์.
์ฆ, ์๋ก ์ฐ๊ณ์์ ๋์์ Session ์ ์ด๋ฅผ ์ฒ๋ฆฌํ๊ฒ ๋ฉ๋๋ค.
• ๋งค ์์ฒญ ๋ง๋ค ํ์ฌ ์ด์ฉ์์ Session ๋ง๋ฃ ์ฌ๋ถ ํ์ธ.
• Session ๋ง๋ฃ ์ ์ฆ์ ๋ง๋ฃ ์ฒ๋ฆฌ.
Session.isExpired() == true
• Logout ์ฒ๋ฆฌ.