4.2.1 Spring Security - authentication

yeonseong Jo·2023년 7월 30일
0

SEB_BE_45

목록 보기
44/47
post-thumbnail

spring을 배우면서 뭘 새롭게 시작하면
django와 비교하기 마련이었는데,
spring security는 비교할게 없었다.

django에서 security에 관해
설정한 것이 없었기 때문..

django를 서비스할 때 cors 오류에 관해
다뤘던 것이 기억이 있긴 한데,
그냥 구글링을 통해 오류만 해결했었다.

그나마 JWT를 이용해 인증을 했긴했는데
생각보단 쉬웠다.

하지만,
spring security를 배우면서
여태 배웠던것 중에 가장 어려운거 같았다.

그래서 보통 블로깅을 하면서 복습을 하는데,
spring security는 복습을 한 번 하고
한 번 더 복습을 하면서 블로깅 중 이다.


Spring Security

Spring Security는
Spring MVC를 기반으로 서블릿 필터를 사용하여
Authentication과 Authoriuzation 및
기타 보안 기능을 제공하는 프레임워크로
사실상 Spring MVC 기반 어플리케이션의
보안 표준이라고 한다.

Authentication?

authentication은 인증으로
해당 사용자가 어플리케이션을
이용할 수 있는 사용자인지 판별해 주는 것

Authorization?

authorization은 인가로
인증을 받은 사용자가 어플리케이션에서
어느 기능을 사용할 수 있는 지 판별해 주는 것

Principal?

principal은 어플리케이션을 사용하는
사용자나, 장치 또는 시스템의 계정 정보를 의미

Authentication

MVC 패턴에 대해 배울 때
사용자의 request는 controller에서부터 시작해서
data를 crud해서 처리한다.

Filter

그래서 처음엔 인증을 어디서 처리하는가 궁금했었는데,
사용자의 request가 controller에 도달하기 전에
서블릿 필터 체인(Servlet Filter Chain)에 포함되어 있는
각 필터에서 요청을 가로채 어떠한 기능을 처리하게 된다.

각 필터는 doFilter()라는 메서드를 구현해야하며,
doFilter에서 어떠한 기능을 수행한다.


하지만, 이 Filter들은 위 그림처럼 Servlet Container
내부에 존재하며,
Spring 어플리케이션에서 작성된 요소들은
Spring Container 내부에 존재하기 때문에,

Spring Security filter들은 사실 Spring Container에
존재한다.

그래서
DelegatingFilterProxy를 통해
Servlet Container 내부에 어떤 filter와
연결하여 해당 fitler 다음에
FilterChainProxy에 존재하는 filter들을 수행할 수 있게 한다.

로그인 인증 흐름

사용자의 로그인 request가 진행되면,
Spring Security의 Filter Chain에 들어오면서
UsernamePasswordAuthenticationFilter가 수행된다.

그 중 attemptAuthentication메서드를 살펴보면,
client의 request 파라미터들 중
username과 password를 사용하여 인증이 되어있지 않은 토큰을 발급하여 AuthenticationManager를 구현한 ProviderManager로 전달한다.

ProviderManagerProvider에 username과 password가 저장되어있는 토큰을 전달하여 인증을 진행하며,

개발자에 의해 AuthenticationProvider를 구현한
Provider는 전달 받은 토큰을 통해
authenticate를 Override한 메서드 내에서
다시 토큰을 UserDetailsService를 구현한 클래스에 전달한다.

개발자에 의해 UserDetailsService를 구현된 클래스에서
loadUserByUsername를 Override한 매서드에서
전달 받은 토큰으로 부터 username과 password를
DB와 대조하여 인증하고,
UserDetails를 구현한 클래스로 만들어진 객체를
return 한다.

다 무사히 인증이 완료 되었으면,
Provider에서 "인증된" 토큰을 생성하여
ProviderManager로 전달하고,
다시 ProviderManager에서
UsernamePasswordAuthenticationFilter로 전달되고,

마지막으로 SeucrityContextHolder에 전달되어
SecurityContext에 인증된 토큰(Authentication)을 저장한다.

이후 세션방식이냐 JWT 방식이냐 등에 따라
인증 정보가 DB에 저장되기도 하고 그냥 인증만 진행 할 수도 있다.


두 번 복습하니 이제 흐름을 이해 한 거 같다.
다음에 몇번 더 봐야 완전히 이해하여 설명을 하지 않을까...?

profile
뒤(back)끝(end)있는 개발자

1개의 댓글

comment-user-thumbnail
2023년 7월 30일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기