프로그램을 배포할 때, 특히 DB가 있는 웹 서비스나 프로그램을 배포할 때 개발자로서 가장 걱정되는 것 중 하나는 역시 보안입니다. 내가 어떻게 막아두든 훨씬 잘하는 공격자들이 마음만 먹으면 얼마든지 공격할 수 있을 것 같기 때문입니다. 사실 보안 전문가와 같이 일하지 않는다면 "완벽한 보안"이란 웹 서비스 개발자들 입장에서는 달성하기 어려운 과제가 아닐까 합니다.
그래도 개발자라면 책임감을 가지고 서버이든, 앱이든 할 수 있는 보안에는 최선을 다해야 합니다. 그러기에 Spring에서도 Admin단에서 효율적인 보안 처리를 도와주는 제공 API가 있는데, 바로 Spring Security 입니다. Spring Security를 배우기에 앞서서는 Spring의 기본적인 사항들, 그리고 Spring의 라이프 사이클 정도는 이해를 한 다음에 시작해야 이해도를 높일 수 있는 것 같습니다.
웹 서비스에서 Administration에 적용해야 하는 보안과 Spring Security 가 어떻게 도와주는지 배우려면 정말 한세월이겠지만, [Spring Security] 포스트들을 준비한다는 마음으로 일단 무작정 적용해보면서 시작해보겠습니다.
Spring Security 의존성 추가
앱 패키지 내 build.gradle 에 다음과 같이 추가해볼게요.
dependencies {
// ... whatever you are using ..
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// ...
}
추가는 했고... 음 그럼 실행해보겠습니다.
2022-11-25 16:42:10.580 INFO 24880 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1848 ms
2022-11-25 16:42:10.829 WARN 24880 --- [ main] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 23dcbaa7-a91c-49d2-88a3-463df0e669d7
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2022-11-25 16:42:10.910 INFO 24880 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@1943c1f2, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@d70f722, org.springframework.security.web.context.SecurityContextPersistenceFilter@518ddd3b, org.springframework.security.web.header.HeaderWriterFilter@5c7dfc05, org.springframework.security.web.csrf.CsrfFilter@705a8dbc, org.springframework.security.web.authentication.logout.LogoutFilter@1b13467c, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@49469ffa, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@497b560e, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@1e1eeedd, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@163042ea, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6e0e5dec, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@48a663e9, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@798256c5, org.springframework.security.web.session.SessionManagementFilter@3d0cac1f, org.springframework.security.web.access.ExceptionTranslationFilter@3c66b7d8, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@6807a356]
2022-11-25 16:42:10.947 INFO 24880 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-11-25 16:42:10.954 INFO 24880 --- [ main] i.s.b.BasicsecurityApplication : Started BasicsecurityApplication in 2.583 seconds (JVM running for 3.003)
로그가 꽤나 달라졌네요! 무슨 비밀번호도 띄워주고, "이거 단순 개발용이니까 진짜 제품에는 사용하지 말아라" 라는 잔소리까지 해줍니다. 그리고 어떤 Spring을 배우든지 실행하면 접속해봐야 하는 국룰을 따라보겠습니다.
.....? 설치만 했는데도 심오한 Security... 역시 보안 영역은 언제나 심오한 것 같네요. 하지만 개발에서는 많은 영역이 그렇듯, 심오해 보이지만 막상 파보면 할 수 있습니다. Security 에 대한 공부를 시작해보죠.
Spring Security 의존성 추가시 일어나는 일들
Spring Security 가 추가되면 정말 많은 일들이 일어나지만, 가장 겉으로만 얘기해보자면 서버를 실행시 Security의 초기화 작업 및 앱에 대한 기 보안 설정이 이루어집니다. 가장 기본 (default)의 구성을 제공해주기 때문에 위에서 비번도 알려주고, 로그인 페이지도 볼 수 있었던 겁니다.
- 아무 설정도 없기 때문에, Spring으로 접근하는 모든 요청은 인증을 요구합니다
- 인증 방식은 Form Login 방식, Http Basic 로그인 방식을 지원합니다
- 기본적인 로그인 페이지를 제공합니다
- 기본 계정 하나를 제공해줍니다 (아이디가 User, 비밀번호가 Log에 찍어준 것)
참고로 Form Login 방식과 Http Basic Login 방식은 Spring Security 에서 만들어서 제공되는 로그인 방식이 아닙니다. 그냥 유명하고 가장 기본적인 웹 상 로그인 방식이에요. 로그인 페이지에서 Id, Pw 를 입력받는 HTML 내의 태그가 <form> 이고, 이 form 묶음을 서버로 전송하여 로그인하는 방식을 말합니다. Http Basic 로그인이란 HTTP 프로토콜 상의 기본 인증 규격에 맞춘다는 의미입니다.
Spring Security는 웹 앱에서 유저의 로그인 및 권한 처리를 관리 / 지원 해주는 프레임워크이기 때문에, 추가 했을 때 Admin 단의 많은 일들이 일어나는 모습을 볼 수 있었습니다. 그럼 개발자가 당연히 내 앱에 대한 보안 설정을 당연히 해줄 수 있겠죠? 그 설정 방식이 어떻게 되는지부터 먼저 알아보겠습니다.
Security 의 핵심 클래스
뭔소리 하는거야 싶으실 수도 있지만, 앞으로 정말 많이 등장할 친구들을 먼저 만나보니까 가벼운 마음으로 보시면 될 것 같습니다. [Spring 기본]에서 열심히 알아봤듯이 Spring은 역할체 Interface와 그를 위한 구현체들에 대한 구분이 정말 자명하게 되어 있기 때문에, 앞으로 그 부분도 잘 기억해보면서 살펴봅시다.
HttpSecurity
HttpSecurity는 나중에 더 자세히 살펴보겠지만, 일단 앱의 보안 설정 정보가 담긴다고 생각하시면 됩니다. 기본적인 보안 설정이 담겨있고, 우리가 더 설정해서 앱에 적용할 것입니다.
WebSecurityConfigurerAdapter
HttpSecurity를 통해서 보안을 직접 설정하고 초기화하는 클래스입니다. 이 Adapter 클래스를 상속받아서 우리의 보안 Configuration 클래스를 만들 것이고, 그 안에서 HttpSecurity를 통해 우리 앱의 적용할 보안 정보를 설정한다 보시면 됩니다.
@Configuration // 아래 Annotation에 포함되어 있어서 사실 안해도 됨
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 인가 정책
http
.authorizeRequests()
.anyRequest().authenticated(); // 모든 요청에 대한 인증을 요구한다
// 인증 정책
http
.formLogin(); // 기본적인 formLogin 방식으로 인증을 할 수 있도록 설정한다
}
}
Configuration 에 대해서는 [Spring 기본]에서 다뤘듯이, CGLIB 클래스를 프록시 형태로 만들어줘서 생성될 Bean 들을 싱글톤으로 관리될 수 있도록 도와줍니다. 해당 Security 클래스를 Bean 으로 등록하여 Spring Container 에서 해당 설정을 관리 대상으로 등록해준다고 보면 됩니다.
EnableWebSeucrity 는 Annotation에 들어가보면 알겠지만, WebSecurityConfiguration, SpringWebMvcIportSelector, Oauth2ImportSelector 3가지 클래스를 import 하겠다는 선언이다. 즉, "해당 설정 클래스를 더불어 Security의 보안을 설정할 것이다"라고 일단 보면 될 것 같습니다. 뭔소린지 하나도 모르겠는겠다면 정상입니다 ^~^
일단 우리가 여기서 중요하게 봐야할 것은 상속 함수 configure 입니다. 해당 함수는 말그대로 [직접 보안세팅을 설정] 하겠다는 함수입니다. 위에서 언급한 HttpSecurity 클래스를 직접 설정하고 그것을 토대로 WebSecurityConfigurerAdapter 가 보안을 초기화 시켜준다고 보면 됩니다. 인증과 인가..?
자 어쨌든 [Spring Security] 를 무작정 추가해봤고, 무작정 중요하다는 설정함수를 넣어봤습니다. 여기까지라도 읽으셨다면 정말 의문 투성이실 것 같습니다.
- 인증과 인가가 뭔가..?
- HttpSecurity는 어떻게 설정하는 건가..?
- WebSecurityConfigurerAdapter는 무슨일을 하는가..?
- 그래서 Spring Security가 하는일이 도대체 뭔가..?
- 그래서 이 포스트가 말하고자 하는게 뭔가.. ?
Spring Security를 대하는 자세 (내 생각)
포스트를 읽으시는 분들의 Security를 찾아보고 계신 목적을 정확히 알 수는 없겠지만, 저는 Security를 통해서 저의 앱에 보안 강화를 하기 위해서 공부를 시작했습니다. 즉, "Security의 내부를 전~부 다 이해해서 나의 것으로 만드는 것"이 목적이 아니였습니다. Spring Security는 Filter 기반의 보안을 지원하기 때문에 정말 복잡하고 매우 깊습니다. "Security의 기본적인 지원과 원리를 이해하고, 그 원리를 토대로 내가 원하는 모습으로 나의 앱에 적용시킨다"가 목적이라면, 이 목적에 맞게 공부를 하는게 맞다고 생각합니다.
바로 위에서 잠깐 보았듯이, Spring Security는 잘 짜여진 API를 사용하는 것이기 때문에, 그 내부를 살펴보면서 원리를 파악할 일이 굉장히 많습니다. 그래야 개발자가 원하는 모습으로 앱에 적용할 수 있기 때문입니다. 그 흐름을 이해하고, 어떤 내부 싸이클을 가지고 있는지를 이해한다면, 여러분이 원하는 OAuth 기반, JWT 기반 등 여러 분야를 적용함에 있어서 훨씬 수준높게 적용할 수 있을 것입니다.
Security 추가는 해봤고, 대충 왜 쓰는지 느낌이 오고, Security 는 내부의 흐름과 원리를 알아보는 것이 공부하는 이유라는 것을 이해하셨다면 충분한 것 같습니다.
출처
1. Spring Security 개발 강의
스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security - 인프런 | 강의
초급에서 중.고급에 이르기까지 스프링 시큐리티의 기본 개념부터 API 사용법과 내부 아키텍처를 학습하게 되고 이를 바탕으로 실전 프로젝트를 완성해 나감으로써 스프링 시큐리티의 인증과
www.inflearn.com
2. 공부할 때 참고했던 블로그
[Security] 스프링 시큐리티의 아키텍처(구조) 및 흐름
Spring Security 스프링 시큐리티리란? 어플리케이션의 보안(인증 및 권한)을 담당하는 프레임워크 Spring Security를 사용하지 않으면 자체적으로 세션을 체크해야 한다. redirect를 일일이 설정해주어야
twer.tistory.com
'Spring > Spring Security' 카테고리의 다른 글
[Spring Security] 아니 왜 Forbidden 만 계속 오지?? (0) | 2023.08.17 |
---|---|
Ajax로 새로운 Security 설정을 연습해보자 (0) | 2022.12.14 |