FROM openjdk:11 # 컴파일 할 jdk 버전
WORKDIR /usr/src/app # 모든 작업 파일 기준 위치
ARG JAR_PATH=./build/libs # 변수 사용하듯이 선언해서 사용
COPY ${JAR_PATH}/IPGeoCheck-0.0.1-SNAPSHOT.jar ${JAR_PATH}/IPGeoCheck-0.0.1-SNAPSHOT.jar
# 빌드한 jar 파일을 도커 컨터이너 내부로 옮겨주는 작업
CMD ["java","-jar","./build/libs/IPGeoCheck-0.0.1-SNAPSHOT.jar"]
# jar 파일 실행 명령
3. 도커 이미지 빌드
- 터미널에서 아래와 같이 명령어 실행(도커 파일이 있는 위치에서)
docker build . -t springbootapp (도커 이미지 빌드)
4. 도커 이미지 실행
- p 옵션을 넣어서 실행한다.
도커 내부 네트워크와 외부 네트워크를 연결하기 위한 포트 연결(로컬 포트 / 도커 내부 포트)
주의 : 포트 옵션을 주지 않으면 도커 이미지를 실행 되었으나 접근이 안되는 현상이 발생된다.
docker run -p 8080:8080 springbootapp(이미지 실행)
※ 문제점 : 어플리케이션 코드의 변경으로 인해서 도커 이미지를 매번 다시 빌드해서 실행해야 한다.
이러한 불편함을 해소하고자 Volume 옵션을 사용한다.
5. 볼륨(Volume) 옵션을 이용한 도커 이미지 실행
docker run -p 8080:8080 -v $(pwd):/usr/src/app springbootapp(볼륨을 사용한 이미지 실행)
# -v "local 참조할 경로" : "참조할 도커 이미지 경로"
Volume 옵션은 실행에 필요한 파일을들 컨테이너 내부에서 참조할 수 있도록 해줍니다.
로컬 경로에 존재하는 모든 파일들을 도커 컨테이너 내부에서 사용할 수 있습니다.
처음 다른 분들의 글들을 둘러보면서 회고록을 볼 때마다 나도 쓰고싶다 써야겠다는 생각을 매번 해 왔었다. "내가 회고를 쓸 정도로 올 한 해 열심히 살았나? 쓸 내용이 있을까?" 이런 생각에 작년에는 회고록을 작성하지 못했다. 하지만 이번에는 한 번 작성해 보려고 한다. 이러한 작은 기록들이 쌓이다 보면 나에게 큰 재산이 될 걸 알기 때문에 어렵게 생각하지 말고 생각나는 대로 올해를 뒤돌아보면서 당장 눈 앞으로 다가온 내년의 2023년 목표를 세워야겠다.
2022년 신년 계획을 생각한게 엊그제 같은데 많은 시간이 지나 벌써 12월 중순이다. 마냥 한게 하나도 없다라고 생각을 했었는데 앉아서 생각해보니 나름 치열하고 열정적으로 발버둥친 한 해 였던것 같기도 하다. 하지만, 2022년 신년 목표로 정한 이직과 목표 금액 모으기는 구체적으로 짜지못해 많은 아쉬움이 남는다. 자신만의 서비스 하는 회사로의 이직을 성공해 회사와 함께 성장하고 싶었던 목표와 무지성 소비를 막기위한 목표 금액 저축이었다. 자산 저축은 어렵지 않은 금액을 목표로 설정해서 성공했지만(목표 금액 미스, 무지성 투자 실패..하..) 이직은 실패하였다.
현재보다 더 좋은 커리어로 업그레이드하기 위해서 매일 시간이 날 때마다 조금이라도 개발 공부를 하고 회사 내에서도 나를 성장시킬 수 있는 좋은 환경으로 바꾸려고 많은 노력을 했음에도 불구하고 시장에서 인정을 받지 못한 것 같아 씁쓸하다.. 그래도 과정에서 경험하고 얻은 건 분명히 있었다. CI, CD를 구성해서 서비스도 만들어보고 (온전히 내 힘으로), 꾸준히 Git에 잔디도 심어 보려고 하고, 기술 블로그 글도 포스팅해보려고 하고, 어떻게 하면 회사에서 더 나은 환경을 찾아가는 경험도 해보고.. 큰 성과는 없었지만 나름의 고민을 하고 고군분투해 보았다.
커리어 외적으로는 남들이 나를 어떻게 생각하는지 굉장히 신경 쓰면서 소심하게 지내왔는데 이러한 생각이 나의 발전에 큰 도움이 되지 않는다고 크게 생각한 한 해이기도 하면서 또한 삶의 방향을 가장 많이 고민한 해이기도 하다. "내 실력을 인정하고 지금의 편안함에 안주하고 제태크에 시선을 돌릴까? 제태크 공부할 시간이 어딨어 스펙 쌓아서 더 좋은 커리어로 업그레이드해야지"라고 불과 며칠 전까지도 고민했지만 이 고민이 부질없다는 것을 깨달았다. 어디에서 나의 포텐이 터질지 모르니 꾸준히 모든 토끼를 잡으려고 노력해야 한다는 것을 알았다. 이 글을 마치고 신년 계획을 세우려 가겠지만 내 신년 목표 구성은 토끼를 잡기위한 문어발식 확장이 될 것 같다. 이렇게 올 한 해를 뒤돌아보니 정리도 되고 내년에 계획을 어떻게 구성하면 좋을지 여러 아이디어도 떠올라서 도움이 된다. 내년 목표를 보다 정량적으로 구체적으로 세워서 성과 있는 회고록으로 다시 돌아오도록 하겠습니다. 2022년 마무리 잘하시고 더 발전한 2023년 맞이하시길! 정말 생각나는 대로 글을 작성해서 읽기 힘든 글 읽어 주셔서 감사드립니다~
SecurityContext를 HTTP session에 캐시(기본 전략)하여 여러 요청에서 Authentication을 공유할 수 있는 공유 필터
SecurityContextRepository를 교체하여 세션을 HTTP session이 아닌 다른 곳에 저장하는 것도 가능하다.
같은 session에서만 공유된다.
스프링 시큐리티 Filter와 FilterChainProxy
스프링 시큐리티 필터는 FilterChainProxy가 호출한다.
여기에 등록되는 필터들은 SecurityConfig에서 설정한 정보가 SecurityFilterChain을 만드는데 사용된다.(FilterChainProxy.getFilters에 SecurityFilterChain)
SecurityConfig 설정에 따라서 등록되는 Filter에 개수가 달라진다.
DelegatingFilterProxy와 FilterChainProxy
DelegatingFilterProxy
일반적인 서블릿 필터(위에서 살펴본 다른 필터들과 같은 서블릿 필터지만 서블릿에 직접 등록되는 필터)
서블릿 필터 처리를 스프링에 들어있는 빈으로 위이함고 싶을 때 사용하는 서블릿 필터
타겟 빈 이름을 설정한다.
스프링 부트 없이 스프링 시큐리티 설정할 때는 AbstractSecurityWebApplicationInitializer를 사용해서 등록
스프링 부트를 사용할 때는 자동으로 등록된다. (SecurityFilterAutoConfiguration)
FilterChainProxy
보통 "springSecurityFilterChain" 이라는 이름의 빈으로 등록된다.
DelegatingFilterProxy
AccessDecisionManager
Access Control 결정을 내리는 인터페이스로, 구현체 3가지를 기본적으로 제공
AffirmativeBased : 여러 Voter중에 한명이라도 허용하면 허용, 기본 전략
ConsensusBased : 다수결
UnanimousBased : 만장일치
AccessDecisionVoter
해당 Authentication이 특정한 Object에 접근할 때 필요한 ConfigAttributes를 만족하는지 확인한다.
WebExpressionVoter : 웹 시큐리티에서 사용하는 기본 구현체, ROLE_Xxxx가 매치하는지 확인
RoleHierarchyVoter : 계층형 ROLE 지원, ADMIN > MANAGER > USER
FilterSecurityInterceptor
AccessDecisionManager를 사용하여 Access Control또는 예외 처리하는 필터.
대부분의 경우 FilterChainProxy에 제일 마지막 필터로 들어있다.
ExceptionTranslationFilter
AuthenticationException
AuthenticationEntryPoint 실행
AbstractSecurityInterceptor 하위 클래스(예, FilterSecurityInterceptor)에서 발생하는 예외만 처리
그렇다면 UsernamePasswordAuthenticationFilter에서 발생한 인증 에러는? UsernamePasswordAuthenticationFilter 자체에서 처리한다.
AccessDeniedException
익명 사용자라면 AuthenticationEntryPoint 실행
익명 사용자가 아니라면 AccessDeniedHandler에게 위임
정리
DeligatingFilterProxy -> FilterChaninProxy -> 시큐리티 필터 목록들(체인들은 어떻게 만들어지는가? WebSecurity, HttpSecurity를 이용해서 만들어진다. 참고 - WebSecurity 주석) -> 인증 관련된 객체(AuthenticationManager) -> 인가 관련된 객체(AccessDecisionManager) -> SecurityContextHolder -> SecurityContext -> Authentication -> Pricipal, GrantAuthority