๋ก๊ทธ์ธ์ ๊ตฌํ ์ํ๊ณ ๋ฐ๋ก Spring security๋ก ํด๋ผ์ด์ธํธ - ์๋ฒ๊ฐ ํต์ ์ํค๋ ค ํ๋ ๋น์ฐํ 403์๋ฌ๊ฐ ์๊พธ ๋์ ์ด๋ฐ๋๋ค.
๋นจ๋ฆฌ ๋ก๊ทธ์ธ์ ๋จผ์ ๊ตฌํํด์ผ ํ ๊ฒ ๊ฐ์๋ฐ... ์ํ๋ ๊ธฐ๋ฅ์ ๋ค ๋ง๋ ํ ์ตํ์ ๋ก๊ทธ์ธ์ ๋ง๋ค๊ณ ์ถ์ด์ ๋ฏธ๋ค๋จ๋ ์ด๋ฆฌ ๊ท์ฐฎ์ ๋๊ฐ๋ฅผ ๋ฐ๊ฒ ๋์๋ค.
๊ทธ๋๋ ๊ณต๋ถํ๋ค ์๊ฐํด์ผ์ง....
1. ์๋๋ ์ด๋ป๊ฒ ๊ด๋ฆฌํ์๋๊ฐ
SecurityConfig๋ ํ๋ก์ ํธ์ ์ ์ฉํ ๋ณด์ ์ ์ฑ ์ ์ค์ ํ๊ณ ์ ์ฉ์ ํ๋ ํด๋์ค์ด๋ค.
์๋ฌด ์ค์ ์์ด ํด๋ผ์ด์ธํธ์ ํต์ ํ๋ ค๋ฉด 403 forbidden์๋ฌ๋ฅผ ๋ง๋๊ฒ ๋ ๊ฒ์ด๋ค.
๊ทธ๋์ ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์ค๋ url์ ํ์ฉ์ํค๊ธฐ ์ํด requestMatchers์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ์๋ค.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/chat/**", "/uploads/**", "/diary/**").permitAll()
.requestMatchers(securityProperties.getPermitUrls().toArray(new String[0])).permitAll()
.anyRequest().authenticated())
.csrf(csrf->csrf.disable())
.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.disable()));
.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.disable())
);
return http.build();
}
๊ทผ๋ฐ ๋ด์ ์๊ฒ ์ง๋ง... ๋ด๊ฐ ์๋ก์ด ํ๋ฉด๊ณผ url์ ๋ง๋ค๋๋ง๋ค ์ ๋ ๊ฒ ๋ฌธ์์ด๋ก ๊ณ์ ์ถ๊ฐํ ์ ์๋ ๋ ธ๋ฆ์ด๋ค.
๊ทธ๋์ ๋ฐ๋ก ๊ด๋ฆฌํ๊ธฐ๋ก ํ๋ค.
2. application.yml ์์ฑ
application.yml์ resource/configํ์ผ์ ์์ฑํ๋ค.
security:
permit-urls:
- /chat/**
- /uploads/**
- /diary/**
์ด์ ์ ๋ ๊ฒ ์์ฑํ๋ฉด ์ url์ ํฌํจํ๋ ํด๋ผ์ด์ธํธ ์์ฒญ์ ๋ฐ์๋ค์ฌ์ง๊ฒ ๋๋ค.
์ฐธ๊ณ ๋ก ,๋ ์ ๋ ๊ธ๋ฌผ! ,๋ ๋ฌด์กฐ๊ฑด ๋บ๊ฒ. ์๋๋ chat, uploads... ์ด๋ ๊ฒ ์ผ๋๋ฐ ์ฝค๋ง๋ฅผ ๋ถ์ด๋๊น ํต์ ์ด ์์ด๋ฃจ์ด์ก๋ค. ์๊ณ ๋ณด๋ ๋ฌธ๋ฒ์ค๋ฅ๋ผ๊ณ
3. ClientSecurityProperties.java ์์ฑ
SecurityConfigํ์ผ์ด ์๋ ๊ฐ์ ํ์ผ ์๋ ClientSecurityPropertiesํ์ผ์ ํ๋ ์์ฑํด์ ๋ง๋ ๋ค.
์ด ํ์ผ์ ์ฉ๋๋ application.yml์ ์ค์ ๊ฐ์ Java ๊ฐ์ฒด๋ก ๋ณํํ์ฌ ๋ณด๊ดํ๋ ํด๋์ค์ด๋ค.
์์์ ๋ณด๋ฉด ์๊ฒ ์ง๋ง, permit-urls์๋ ๋ค์ํ URL์ด ๋ด๊ฒจ์์ผ๋ฏ๋ก ๋ฐ๋์ List<String>์ผ๋ก ์ ์ฅํด๋ฌ์ผ ํ๋ค.
๋ฐ๋ผ์ ์๋ฃํ์ List<String>์ด๋ค.
@Configuration
@ConfigurationProperties(prefix="security")
public class ClientSecurityProperties {
// private Field
private List<String> permitUrls;
// getter
private List<String> getPermitUrls() {
return permitUrls;
}
// setter
private void setPermitUrls() {
this.permitUrls = permitUrls;
}
}
ClientSecurityProperties์ ์ญํ ์ ๋ค์๊ณผ ๊ฐ๋ค.
1๏ธโฃ application.yml์ ๊ฐ์ Java ๊ฐ์ฒด๋ก ๋ฐ์ธ๋ฉ
application.yml ํน์ application.properties์ ๊ฐ์ ์๋ฐ ์ฝ๋ ๋ด์์ List<String>์๋ฃ๊ตฌ์กฐ๋ก ์ฌ์ฉํ๋ ค๋ฉด ํน์ ๊ฐ์ฒด์ ํ๋์ ๋งคํํ๋ ๊ณผ์ ์ด ํ์ํ๋ค.
- @Configuration : @Component๋ฅผ ์ฌ์ฉํด๋ ์๊ด์ ์์ง๋ง, ์ค์ ๊ณผ ๊ด๋ จ๋ ํ์ผ์์ ๋ช ์ํ๊ธฐ ์ํด @Configuration์ ์์ฑํ๋๊ฒ ๊ด๋ก์ด๋ค. ์ง๊ธ ์ด ํด๋์๊ทธ '์ค์ ํด๋์ค'์์ ๋ช ์ํ์ฌ Spring ์ปจํ ์ด๋์ ๋ฑ๋ก๋๊ฒ ํ๋ค.
- @ConfigurationProperties(perfix="security") : appication.yml์ security: ์๋์ ๋ชจ๋ ์์ฑ์ ์ด ํด๋์ค์ ๋งคํ์ํจ๋ค.
- ex) chat, uploads, diary๋ฅผ ๋ชจ๋ List<String>์ ํํ๋ก permitUrls์ ๋งคํ

2๏ธโฃ Spring Bean์ผ๋ก ๋ฑ๋ก ๋ฐ ์์กด์ฑ ์ฃผ์ (DI)
SecurityConfig์์ permitUrls๋ชฉ๋ก์ ์ฌ์ฉํ๋ ค๋ฉด ClientSecurityProperties์ ์ธ์คํด์ค๊ฐ Spring IoC ์ปจํ ์ด๋์ ์ํด ๊ด๋ฆฌ๋๋ Bean์ผ๋ก ๋ฑ๋ก๋์ผ ํ๋ค.
SecurityConfig์ ์์ฑ์์์ ClientSecurityProperties๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ์์กด์ฑ ์ฃผ์ (DI)๋ฅผ ์คํํ ์ ์๋๋ก ํ๋ค. 'ClientSecurityProperties์ ๋ํ SecurityConfig์ ์์กด'
๋ฐ๋ผ์ SecurityConfig์์
// SecurityConfig
public class SecurityConfig {
... ์๋ต,
private final ClientSecurityProperties securityProperties; // ์์กด์ฑ ์ฃผ์
(DI)
์์ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.

3๏ธโฃ๋์ ์ธ ๋ชฉ๋ก ์ฌ์ฉ
๋ชฉ๋ก์ด ์๋ ๋จ์ผ ๊ฐ(String)์ด๋ผ๋ฉด @Value๋ฅผ ์ด์ฉํ ์๋ ์์ง๋ง, ์ง๊ธ๊ณผ ๊ฐ์ด(chat, upload, diary....) ์ฌ๋ฌ๊ฐ๋ฅผ ๊ด๋ฆฌํ๋ ์ํฉ์ผ ๋ @ConfigurationProperties๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๊ถ์ฅ๋๋ค.
๊ฒฐ๋ก : SecurityConfig.java์ application.yml์ '์ค๊ฐ ๋ค๋ฆฌ' ์ญํ
โ๊ธฐ๋ณธ ์์ฑ์์ ๋งค๊ฐ๋ณ์ ์์ฑ์
๊ธฐ๋ณธ ์์ฑ์์ ํํ : public ClientSecurityProperties() {}
- ๋ฐ๋์ public์ด์ด์ผ ํ๋ค
- ํ์ฌ ์ฝ๋์์ ์๋ ์ด์ : Java Compiler๊ฐ ์๋์ผ๋ก ๊ธฐ๋ณธ์์ฑ์๋ฅผ ๋ง๋ ์ํ์ด๋ค
- setter ๋ฐฉ์ ๋ฐ์ธ๋ฉ์ ์ํด์๋ผ๋ @ConfigurationProperties๋ ๊ธฐ๋ณธ ์์ฑ์๊ฐ ์์ด์ผ ํ๋ค.
๋งค๊ฐ ๋ณ์ ์์ฑ์์ ํํ : public SecurityConfig(ClientSecurityProperties securityProperty) { }
- ํ์ฌ ์ฝ๋์์ Spring Security ์ค์ ์์ ๊ฐ์ฅ ๊ถ์ฅ๋๋ ๋ฐฉ์์ธ ์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํ๊ณ ์๋ค.
// ๊ธฐ๋ณธ ์์ฑ์์ ํํ
public ClientSecurityProperties(){}
// ๋งค๊ฐ๋ณ์ ์์ฑ์์ ํํ
public SecurityConfig(ClientSecurityProperties securityProperty) {}
โJava Compiler VS JVM
- Java Compiler : .java ์์ .class๋ก ๋ณํ, ์ปดํ์ผ ์์ ์ ์คํ๋จ
- JVM : .class๋ฅผ ์คํ, Run ์์ ์์ ์คํ๋จ
โ Getter, Setter, this ํค์๋
// Getter์ ํํ
public List<String> getPermitUrls() {
return permitUrls;
}
// Setter์ ํํ
public void setPermitUrls() {
this.permitUrls = permitUrls;
}
๊ณ์ ๋กฌ๋ณต์ฐ๋ค ์ด๊ฑฐ ๋ณด๋๊น ์ข ๋ฐ๊ฐ๊ณ ... ์ค๋๋ง์ธ๊ฑฐ ๊ฐ๋ค...

๊ฐ๋จํ ๋ณต์ต ์ฐจ์์์ ์ ๋ฆฌํ๋ค..
- Getter, Setter์ ๋ํด ๋ ์์ธํ๊ฒ ์ฝ์๋ ค๋ฉด ์ฌ๊ธฐ ํด๋ฆญ
- โญthis : ํ์ฌ ๊ฐ์ฒด(์ธ์คํด์ค) ์์ , ์ฌ๊ธฐ์ ์ฆ ClientSecurityProperties ๊ทธ ์์ฒด๋ฅผ ๊ฐ๋ฆฌํด. ๋ฐ๋ผ์ this.permitUrls๋ ClientSecurityProperties์ permitUrls๋ฅผ ๊ฐ๋ฆฌํค๋ ๊ฒ์ผ๋ก, ํ์ฌ ๊ฐ์ฒด ํ๋๋ฅผ ์๋ฏธํ๋ค.
4. SecurityConfig ์์ฑ
SecurityConfig์ ์ญํ ์ 1๏ธโฃ๋ณด์ ํํฐ ์์ด ์ฒด์ธ ๊ตฌ์ฑ, 2๏ธโฃ์ธ์ฆ ์์ด ์ ๊ทผ ๊ฐ๋ฅํ URL ์ค์ , 3๏ธโฃ๋ชจ๋ HTTP์์ฒญ์ ๋ํ ๋ณด์ ๊ฒ์ฆ ์ํ์ด๋ค.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final ClientSecurityProperties securityProperties; // DI์ค๋น
public SecurityConfig(ClientSecurityProperties securityProperties) {
this.securityProperties = securityProperties; // DI
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers(securityProperties.getPermitUrls().toArray(new String[0])).permitAll()
.anyRequest(). authenticated())
.csrf(csrf -> csrf.disable())
.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.disable())
);
return http.build();
}
}
- @Configuration์ ์๊ณผ ๊ฐ๋ค. ํด๋น Javaํ์ผ์ด 'Spring ์ค์ ํด๋์ค'์์ ์ ์ธ
- @EnableWebSecurity : Spring Security์ ํต์ฌ ๊ธฐ๋ฅ์ ํ์ฑํํ๊ณ , ์น ๋ณด์ ์ค์ ์ ์ด ํด๋์ค(SecurityConfig)์์ ์ค์ ํ๋ค๋ ๋ป์ ์ด๋ ธํ ์ด์
์ฌ๊ธฐ์๋ ์๊น์ ๋ง์ฐฌ๊ฐ์ง๋ก this์ ๋ํด์ ๋ณต์ตํ ์ ์๋ค.
1๏ธโฃ ์์กด์ฑ ์ฃผ์ (DI)
- private final ClientSecurityProperties securityProperties
- โญ= SecurityConfig์ ํ๋๋ถ โญ
- ๊ธฐ์กด์ ์ ์ํ๋ ClientSecurityProperties Bean์ ์ฃผ์ ๋ฐ์ ํ๋ ์ค๋น
- Spring Boot๋ ์์ฑ์ ์ฃผ์ ๋ฐฉ์์ ์ฌ์ฉํ๋๋ฐ, Spring ์ปจํ ์ด๋๋ ClientSecurityProperties Bean์ ์ฐพ์์ SecurityConfig ์์ฑ ์ ์์ฑ์ ๋งค๊ฐ๋ณ์๋ก ClientSecurityProperties๋ฅผ ์๋์ผ๋ก ์ ๋ฌํ ์ ์๋๋ก ์ธํ
- public SecurityConfig(ClientSecurityProperties securityProperties){}
- ๋งค๊ฐ๋ณ์๊ฐ ์๋ ์์ฑ์
- ๋งค๊ฐ๋ณ์๋ฅผ ํตํด ClientSecurityProperties๋ฅผ ์ฃผ์ ๋ฐ์(DI์คํ)
- ๊ธฐ๋ณธ ์์ฑ์๋ ๋งค๊ฐ๋ณ์๊ฐ ์๋ค. ex) public SecurityConfig() {}์ ๊ฐ์ด
- this.securityProperties = securityProperties;
- ํท๊ฐ๋ฆฌ์ง ๋ง๊ฒ! ์ฌ๊ธฐ์ this๋ ClientSecurityProperties๊ฐ ์๋ SecurityConfig
- ๋ฐ๋ผ์ private final ClientSecurityProperties securityProperties๋ SecurityConfig์ ํ๋๋ถ
- securityProperties : ClientSecurityProperties์์ ๋ฐ์ ๊ฐ๋ค์ ์ฌ์ฉํ ์ ์๋๋ก ๋์ ํจ

2๏ธโฃ ๋ณด์ ํํฐ ์ฒด์ธ ์ค์
Spring Security ํต์ฌ ๋ณด์ ์ ์ฑ ์ ์ค์ ํ๋ ๊ณณ
- authorizeHttpRequests : ์ ๊ทผ ๊ถํ ์ค์ ์์ญ
- authorizeHttpRequests(auth -> auth...) : Http ์์ฒญ์ ๋ํ ๊ฒ์ฆ ์์ ์ ์ธ
- .requestMatchers(...).permitAll() : ClientSecurityProperties์์ ๊ฐ์ ธ์จ URL ๋ชฉ๋ก์ ํด๋นํ๋ ์์ฒญ๋ค์ ์ธ์ฆ ์์ด ์ ๊ทผ์ ํ์ฉ
- .anyRequest().authenticated() : ์์ ๊ท์น์ ํด๋น๋์ง ์๋ ๋ชจ๋ ์์ฒญ๋ค์ ์ ๊ทผ์ ํ์ฉํ๋๋ก ๊ฐ์ (ex. ๋ก๊ทธ์ธ ํ์ etc)
- .csrf(csrf -> csrf.disable()) : CSRF ๋ณดํธ ๊ธฐ๋ฅ์ ๋นํ์ฑํ
- .headers(headers -> headers.frameOptions(frameOptions -> frameOptions.disable()) : X-Frame-Options ํค๋ ์ค์ ์ ๋นํ์ฑํ. ์ฃผ๋ก iFrame ๋ด์์ ํ์ด์ง ๋ก๋๋ฅผ ํ์ฉํด์ผ ํ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋จ
- return http.build() : ์ค์ ๋ณด์์ด ๋ชจ๋ ๊ฐ์ถฐ์ง SecurityFilterChain ๊ฐ์ฒด๋ฅผ ๋ฐํ, Spring Bean์ผ๋ก ๋ฑ๋ก. ์ค์ ์น ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ณด์ ํํฐ ์ฒด์ธ์ผ๋ก ์ฌ์ฉ
5. ๊ฒฐ๊ณผ


์ ํต์ ํด์ API ์ฐ๊ฒฐ๋๋๊ฒ ํ์ธ!
'Backend๐ฅ๏ธ > Javaโ(Spring๐)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [Spring] Spring Security ๋ง๋ณด๊ธฐ (0) | 2025.12.11 |
|---|---|
| [Java]API ํธ์ถํด์ ๋ฌธ์ ๋ณด๋ด๊ธฐ๐จ (4) | 2025.06.12 |
| [Java] length, length(), size()์ ์ฐจ์ด (2) | 2024.12.15 |