728x90
반응형
SMALL
보안이 왜 중요한가?
- 데이터 손실 또는 비즈니스 로직 손실을 초래할 수 있음
- 이러한 손실은 법적 처벌까지 따라갈 수 있다.
- 대부분의 공격에 대해 회피하고 정보를 보호하기 위함
환경 구성
- Java 17, Spring Web, devtools, Spring Security
- Spring security 의존성을 추가하게되면 어떠한 요청에도 응답하지 않고 자격증명을 요구한다.
아무것도 설정하지 않은 Security 프로젝트
- 첫 인증후에는 곧바로 들어갈 수 있다.
- 재시작할때마다 새로운 빔리번호를 받고 가장 낮은 cvrt어플리케이션에서는 작동하지 않을 수 있다.
- 저장 시스템에 자격증명을 저장하고나 자격증명을 요구하는 것
properties 설정
- 비생산 애플리케이션, 내부 애플리케이션 , 작은 poc어플리케이션을 만들 때 사용하면 편하다.
왜 SpringSecurity를 사용하는가?
- 우리는 그저 웹 어플리케이션에서 프레임워크를 사용해서 대부분의 고객들의 새로운 요구사항에 더 집중할 수 있다.
- 모든 보안 시나리오를 참고해서 만든 고급 프레임워크
- 최소한의 설정으로 보안 프레임워크를 사용할 수 있다.
- 오픈 소스로 무료이다.
- CSRF, CORs와 같은 취약점을 다룬다. 매일매일 Security팀이 패치를 하고 있다.
- 역할 기반 매커니즘으로 역할 부여 가능
- JWT tokens , Oauth2, Open Id 등을 사용할 수 있다.
Servlets & Filters
- 어떤 Java Web Applications이든지 요청을 받은 후 그것을 HTTP 프로토콜로 전송한다.
- 우리 브라우저는 HTTP프로토콜로만 이해할 수 있기 떄문이다.
- 자바코드는 HTTP 프로토콜을 이해 할 수 없기 때문에 중간에서 Servlet COntainer가 중재한다. (톰캣같은)
- 브라우저로부터 받은 HTTP 메세지를 ServletRequest object로 변환한다.
- 이 Object는 자바 코드 프레임워크에서도 동일하게 사용된다.
- 다시 요청을 보내려고 할 때 서블릿은 오브젝트를 브라우저가 이해할 수 있는 HTTP 메시지로 변환한다.
- 필터는 특별한 서블릿으로 들어오는 모든 요청을 가로챌 수 있다.
- 이러한 필터에는 실질적인 비즈니스 로직이 실행되기 전,요청,응답 오브젝트를 보내기 전 일어났으면 하는 프리로직을 넣을 수 있다.
Spring Security Internal Flow
- 유저가 로그인 페이지에 본인의 자격 증명을 입력
- 클라이언트는 백엔드에 자격증명요청을 보낸다.
- Spring Security는 자체적으로 개발한 필터를 이용해서 백엔드 서버에 들어오는 모든 요청을 감시한다.
- 접근하고자 하는 경로를 확인하여 보호된 자원인지 공개적으로 접근 가능한 자원인지 확인한다.
- 두 번째부터는 유저가 이미 로그인했는지 체크하는 로직을 갖출것이다. 그에 따라 첫 번째 로그인 단계에서 발생한 기존 세션 Id나 기존 토큰을 활용할 것이다.
- 유저의 아이디와 비밀번호를 인증객체에 저장한다. 유저의 정보와 자격 만을 저장
- 이 요청을 인증 관리자로 넘긴다.
- 제 웹 어플리케이션안에 어떤 인증 제공자가 존재하는지 체크한다.
- 어떤 dB나 ldap서버에서 , 권한부여 서버나 나의 캐시에서 유저 자격증명을 확인할 것이다.
- 유저네임과 비밀번호 인증, OR매핑 역할 등 여러 인증제공자를 역할을 나눌 수 있다.
- 특정 욫어에대해 유효한 인증 제공자가 어떤 것인지 확인하는 것이 인증 관리자의 책임
- 해당 인증 관리자 이요청을 인증 제공자들중 하나에 보낸다.
- 관리자가 첫 번째 인증 제공자에 요청을 전송했고 인증이 실패한 시나리오인 경우 단순히 로그인에 실패했다는 응답을 보내느것뿐만 아니라 대신 가능한 모든 인증 제공자들을 시도한다.
- 모든 인증 관리자를 시도했고 모든 시도에서 인증 실패한 시점에서야 인증 관리자는 엔드 유저에게 인증이 실패했다고 응답한다.
- 이게 인증관리자의 역할이고 인증 제공자로 돌와와서 여기를 보면 다수의 인증 제공자가 있을 수 있다.
- 우리가 설정할 수 있다.
- 인증 제공자안에서 실질적인 로직을 만들 수 있으며 Spring Security에서 제공하는 다양한 인터페이스와 클래스를 UserDetails Manager,Service에서 사용가능하다.
- 우리의 요구사항은 단순히 데이터베이스같은 저장소나 LDAP로부터 유저 정보를 불러오는 것이기 때문
- 이 유저 정보를 불러온 다음 엔드 유저가 제공한 정보와 저장소 안에 저장된 정보를 비교할 수 있다.
- 이 모든 사전 정의된 로직은 대부분의 프로젝트에서 요구하는 로직인데 UserDetailsManager, Service인터페이스에서 제공된다.
- 직접 커스텀도 가능하다.
- 취약한 보안을 회피하기 위해 비밀번호를 저장소에 저장하거나 엔드 유저가 제공한 비밀번호를 확인하고자할때는 항상 암호화 또는 해싱을 해야 한다.
- 표준과 로직을 수행하기 위해서 PasswordEncoder에 이 내용이 구현되어 있다.
- 엔드 유저가 제공한 자격 증명이 유효한지 유저디테일 매니저와 서비스, 패스워드 엔코더가 협동해서 알려준다.
- 모든 과정이 끝나고 이 정보는 SpringSecurity필터들로 돌아간다.
- 응답을 엔드유저에게 전달하기 전에 2단계에서 이들이 생성한 인증 객체를 보안 컨텍스트에 저장한다.
- 보안컨텍스트에 저장하는 객체 정보는 인증이 성공적이었는지 세션 아이디가 무엇인지 저장한다.
- 이 컨텍스트 덕분에 첫 번째 로그인이 성공적일경우 두번째부터는 자격증명을 요구하지 않는다.
- 모든 과정이 끝나면 response가 해당 클라이언트에게 제공된다.
주요 필터와 역할
- Authorization 필터
- 엔드 유저가 접근하고자하는 URL에 접근을 제한하는 것
- 공개 URL이라면 응답은 자격증명을 요구하지 않는다.
- 해당 필터는 보안 URL접근 요청을 멈추고 해당 요청을 SpringSecurity필터 체인의 다음 필터로 리다이렉트 한다.
- doFilter
- 해당 필터가 보안 URL인지 체크한다.
- DefaultLoginpageGenerating Filter
- 초기 로그인 페이지가 해당 필터에 의해 생성된 것
- UsernamePasswordAuthentication Filter
- 유저가 아이디와 비밀번호를 입력시 수신하는 http의 출력 요청으로부터 유저 네임과 비밀번호를 추출하는 것
- 추출한 아이디와 비밀번호는 UsernamePasswordAuthenticationToken 객체에 저장된다.
- daoAuthenticationProvider
- AbstractUserDetailsAuthenticationProvier 객체를 상속받음
- 내부에는 Authenticate 메서드가 존재한다.
- 해당 메서드에 ProviderManager는 요청을 전송하고 이 메서드 안에서 모든 실제 인증 로직이 반환되는 것을 확인할 수 있다.
- retriveUser에서는 인증 제공자가 유저 디테일 매니저,서비스의 도움을 받는다.
- userDetailsManager와 UserDetailsPasswordService 인터페이스를 상속받은 InmemoryUserDetailsManager클래스가 있다. 유저 정보는 해당 클래스에 저장된다.
- 이 클래스는 loadUserByUsername에의해 호출된다.
Security 전체 흐름 디버그
- Authorization 필터
- DefaultLoginPageGenerating Filter
- 로그인시 UsernamePasswordAUthentication Filter ( username,password 추출 , UsernamePasswordAuthenticationToken 객체 생성) , ProvideManager호출
- Manager의 Authentcation메서드 수행, 모든 인증 제공자는 ProvideManager에의해 수행
- InmemoryUserDetailsManager에 의해 유저 정보가 불러와지고
- daoAuthenticationProvider 에 전달된다.
- 인증 제공자는 PasswordEncoder의 동무을 받아 인증을 수행하고 성공시 ProviderManager은 같은 내용을 SecurityFilter에전달하고 엔드 유저는 성공적인 응답을 얻게 된다.
Security는 한 번 자세히 공부하고 코드를 알아두면 언제든지 사용할 수 있는 좋은 프레임워크인것 같다.
앞으로 Authentication 부터 AuthenticationManager,Provider,DetailService 등을 모두 순서대로 코드와 함께 포스팅해보도록 하겠다.
https://sunro1994.tistory.com/184
[Java - Spring Security6] Config파일 해석 및 직접 FilterChain만들기
우선 내 컨트롤러 다이어그램을 먼저 보여주자면! Controller Diagram 모든 컨트롤러는 REST API로 호출하는 방식이며 Spring Security 프레임워크가 적용되어있다. 모든 API호출 경로는 Security에서 인증 및
sunro1994.tistory.com
728x90
반응형
SMALL
'Spring > Security6' 카테고리의 다른 글
[Java - Spring Security6] Authentication(인증)과 관련된 Provider와 manager (0) | 2024.03.05 |
---|---|
[Java - Spring Security6] PasswordEncoder와 BCryptPasswordEncoder, 그 이외의 암호화 클래스들 (0) | 2024.03.04 |
[Java - Spring Security6] Config파일 해석 및 직접 FilterChain만들기 (1) | 2024.03.02 |
자바[Java] - Security 소개 (1) | 2023.12.11 |