๐ก Spring Secuirty 6.3.3์ Spring Security/Servlet Applications ๋ฌธ์๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ฑํ์์ต๋๋ค
์์กด์ฑ ์ถ๊ฐ
Gradle์์๋ ๋ค์์ ์์กด์ฑ์ ์ถ๊ฐํ์ฌ Spring Secuirty์ ๋ํ ์์กด์ฑ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
dependencies {
implementation "org.springframework.boot:spring-boot-starter-security"
}
Starting Hello Spring Security Boot
๊ณต์ ๋ฌธ์์์ ๋ค์๊ณผ ๊ฐ์ Spring Security Starter Application์ ์ ๊ณตํฉ๋๋ค.
์ด๋ฅผ ์คํํ๋ฉด ์ธํ ๋ฆฌ์ ์ด์ ์คํ ์๋์ฐ์ ๋ํ๋๋ ๋ฌธ์ฅ ์ค ๋ค์์ ์ฐพ์ ์ ์๋๋ฐ, ์ด๋ ์ฑ์์ ์คํ๋ง์ํ๋ฆฌํฐ๊ฐ ์ ์ฉ๋์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์คํ๋ง ์ํ๋ฆฌํฐ ์ ์ฉ ์, “generated security password”๋ก ์ ๊ณต๋ credential ์์ด ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋ด๋ฉด, ์คํ๋ง ์ํ๋ฆฌํฐ๋ ๊ถํ์ด ์๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ๊ณ 401 Unauthorized ๋ก ์๋ตํฉ๋๋ค.
$ curl -i <http://localhost:8080/some/path>
HTTP/1.1 401
...
๋ค์๊ณผ ๊ฐ์ด credential๊ณผ ํจ๊ป ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋ด๋ฉด, ๊ฒฝ๋ก๊ฐ ์๊ธฐ ๋๋ฌธ์ 404 Not Found๋ก ์๋ตํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
$ curl -i -u user:8e557245-73e2-4286-969a-ff57fe326336 <http://localhost:8080/some/path>
HTTP/1.1 404
...
Runtime Expectations
Spring Boot์ Spring Security๋ฅผ ์ ์ฉํ๋ฉด, ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐํ์ ์์์ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ด ์ ๊ณต๋ฉ๋๋ค.
- ๋ชจ๋ ์๋ํฌ์ธํธ์ ๋ํด ์ธ์ฆ๋ ์ฌ์ฉ์๋ฅผ ์๊ตฌํฉ๋๋ค.
- ์๋ฒ ์์ ์ ์์ฑ๋ ํจ์ค์๋๋ฅผ ํตํด ๊ธฐ๋ณธ ์ฌ์ฉ์๋ฅผ ๋ฑ๋กํฉ๋๋ค.
- BCrypt๋ฅผ ๋น๋กฏํ ์ํธํ ๋ฐฉ์๋ค๋ก ๋น๋ฐ๋ฒํธ ์ ์ฅ์๋ฅผ ๋ณดํธํฉ๋๋ค.
- ํผ ๊ธฐ๋ฐ ๋ก๊ทธ์ธ/๋ก๊ทธ์์์ ์ ๊ณตํฉ๋๋ค.
- HTTP Basic, ํผ ๊ธฐ๋ฐ ๋ก๊ทธ์ธ์์ ์ธ์ฆ์ ์ํํฉ๋๋ค
- ์น ์์ฒญ์ ๋ํด์๋ ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ, ์๋น์ค ์์ฒญ์ ๋ํด์๋ 401 Unauthorized๋ก ์๋ตํฉ๋๋ค.
- CSRF ๊ณต๊ฒฉ์ ๋ง์ต๋๋ค.
- ์ธ์ ๊ณ ์ ๊ณต๊ฒฉ์ ๋ง์ต๋๋ค.
- (์๋ต)
๐ก CSRF ๊ณต๊ฒฉ์ด๋?
Cross-Site Request Fogery.
๊ณต๊ฒฉ์๊ฐ ์ธ์ฆ๋ ์ฌ์ฉ์๊ฐ ์ฌ์ฉํ๊ณ ์๋ ์ฌ์ฉ์๋ฅผ ํตํด ๊ฐ์ ๋ก ์์ฒญ์ ๋ณด๋ด๊ฒ ํ๋ ์ดํ๋ฆฌ์ผ์ด์ ์ทจ์ฝ์ ๊ณต๊ฒฉ
- Spring Boot Security Auto Configuration
@EnableWebSecurity //@EnableWebSecurity ์ด๋
ธํ
์ด์
์ ์ถ๊ฐํฉ๋๋ค.
@Configuration
public class DefaultSecurityConfig {
@Bean
@ConditionalOnMissingBean(UserDetailsService.class)
InMemoryUserDetailsManager inMemoryUserDetailsManager() {
// "user"๋ผ๋ ์ ์ ๋ค์๊ณผ ์ฑ ์คํ ์ ์ฝ์์ ๋์๋ ๋๋ค์ผ๋ก ์์ฑ๋ ๋น๋ฐ๋ฒํธ์ ๋ํด
// UserDetailsService๋ผ๋ ๋น์ ๋ฐํํฉ๋๋ค.
String generatedPassword = // ...;
return new InMemoryUserDetailsManager(User.withUsername("user")
.password(generatedPassword).roles("USER").build());
}
@Bean
@ConditionalOnMissingBean(AuthenticationEventPublisher.class)
DefaultAuthenticationEventPublisher defaultAuthenticationEventPublisher(ApplicationEventPublisher delegate) {
// ์ธ์ฆ ์ด๋ฒคํธ๋ฅผ ์ํด AuthenticationEventPublisher ๋น์ ๋ฐํํฉ๋๋ค.
return new DefaultAuthenticationEventPublisher(delegate);
}
}
Security Use Cases
์คํ๋ง ์ํ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ํ ๋ณด์ ๊ณผ์ ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ฃผ ์ฌ์ฉ ์ผ์ด์ค๋ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- REST API ์ค๊ณ ์ JWT ๋๋ ๋ค๋ฅธ ํ ํฐ์ ์ด์ฉํ ์ธ์ฆ ์ถ๊ฐ
- ์น์ฑ, API ๊ฒ์ดํธ์จ์ด ๋ฑ์์
- OAuth 2.0์ด๋ OIDC ๋ก๊ทธ์ธ ์ถ๊ฐ
- SAML 2.0์ ์ด์ฉํ ๋ก๊ทธ์ธ ์ถ๊ฐ
- CAS๋ฅผ ์ด์ฉํ ๋ก๊ทธ์ธ ์ถ๊ฐ
- ๋ค์์ ๊ด๋ฆฌํ ๋
- Spring Data, JDBC๋ฑ์ ์ด์ฉํด LDAP๋ Active Directory์ ์ ์ ๊ด๋ฆฌ
- ๋น๋ฐ๋ฒํธ ๊ด๋ฆฌ
์์ ์ฌ๋ก ๋ง๊ณ ๋ ๋ค์ ์์๋๋ก ์ดํ๋ฆฌ์ผ์ด์ ์ ์๊ฐํ ์ ์์ต๋๋ค.
- ํ๋กํ ์ฝ
- Spring Security๋ Servlet ๊ธฐ๋ฐ ์ดํ๋ฆฌ์ผ์ด์ ๋ค์์ HTTP์ Websocket์ ์ง์ํฉ๋๋ค.
- ์ธ์ฆ
- ์ด๋ป๊ฒ ์ฌ์ฉ์๋ค์ด ์ธ์ฆ์ ๋ฐ๊ณ , ๊ทธ ์ธ์ฆ์ด stateful์ผ์ง, stateless์ผ์ง ๊ณ ๋ คํ์ธ์
- ์ธ๊ฐ
- ๊ทธ๋ฆฌ๊ณ , ์ ์ ์๊ฒ ์ด๋ค ๊ถํ์ด ๋ถ์ฌ๋์๋์ง๋ฅผ ๊ฒฐ์ ํ์ธ์
- ๋ง์ง๋ง์ผ๋ก Spring Security์ default protection๊ณผ ๊ฒฐํฉํ์ฌ ์ด๋ค ์ถ๊ฐ protection์ด ํ์ํ์ง๋ฅผ ๊ณ ๋ คํ์ธ์
'๊ณต๋ถ ๊ธฐ๋ก > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๋ฐ ๊ฐ์ฒด ์งํฅ์ ์๋ฆฌ์ ์ดํด] 03 ์๋ฐ์ ๊ฐ์ฒด ์งํฅ (1) (0) | 2024.05.05 |
---|---|
[์๋ฐ ๊ฐ์ฒด ์งํฅ์ ์๋ฆฌ์ ์ดํด] 01-02 ์ ๋ฆฌ (0) | 2024.04.21 |