Spring Security Fundamentals(1)

Crow·2022년 11월 10일
0

InflearnOAuth2

목록 보기
3/12

1. 시큐리티 인증 및 인가 흐름 요약

Authentication흐름

제일 먼저 사용자가 로그인요청 -> DelegatingFilterProxy->
FilterChainProxy-> AuthenticaitonFilter ->
Authentication-> AuthenticationManager
-> AuthenticationProvider -> UserDetailsService ->
UserDetails -> UserDetailsService -> AuthenticationProvider -> PasswordEncoder ->
Authentication -> AuthenticationManager -> AuthenticaitonFilter -> SecurityContext

Authorization흐름

사용자가 특정 페이지에 접근 -> Authentication흐름 -> ExceptionTranslationFilter-> FilterSecurityInterceptor -> AccessDecisionManager ->
AccessDecisionVoter

Servlet Filter 계층

DelegatingFilterProxy :

사용자가 요청할때 그 요청을 받는쪽은 Servlet 즉 Container EX:WAS)는 FilterChainProxy로 전달만함

FilterChainProxy :

Spring Security의 여러 Filter들을 호출하며 사용자의 요청을 처리

Authentication 계층

AuthenticaitonFilter :

인증필터이며 가장 유명한 것으로 UsernamePasswordAuthenticationFilter가 존재함
해당 필터는 Form로그인 인증을 하는 필터 일반적으론 /login URL형태로 호출됨

이 필터가 가장먼저 하는 일은 Authentication 인터페이스 구현체를 만들고 사용자가 입력한 ID & PASSWORD를 저장하고 Filter가 Authentication인증 객체를 전달함과 동시에 AuthenticationManager 호출

인증에 성공해 최종적으로 반환된 Authentication를 SecurityContext에 저장해줌

Authentication :

인증절차 초기에 AuthenticaitonFilter가 만드는 사용자가 입력한 ID & PASSWORD저장하는 객체이며

AuthenticationProvider가 최종 검증에 성공시 UserDetails타입의 객체를 저장(이때 데이터 뿐만 아니라 해당 유저가 가지고 있는 권한도 포함됨)해서 다시 만드는 객체 이기도함

AuthenticationManager :

이 클래스도 사실상 많은 일 처리를 하지 않음 보안과 관련된 본질적인 처리 X
인증 처리를 할수 있는 실질적인 클래스인 AuthenticationProvider를 찾아서 Authentication 객체를 위임하는 일만 함

AuthenticationProvider :

실제로 아이디와 패스워드를 최종적으로 검증해서 인증 성공 여부에 따라서 처리해주는 클래스
먼저 사용자의 계정이 시스템에 있는지 검사하고
이때 AuthenticationProvider가 UserDetailsService타입의 클래스사용 (UserDetailsService는 Interface인대 그걸 상속받아서 커스텀 클래스를 만들어서 사용도 가능) 나 역시 해당 방식으로 구현한 경우가 존재함

ID의 인증이 성공했다면 다음으로 반환된 객체를 가지고 Password를 검증해야함 그때 사용하는게 PasswordEncoder임

최종적으로 ID & PASSWORD 인증에 성공했다면 Authentication객체를 다시 만듬 이후 Authentication를 역순으로 Filter까지 전달(AuthenticationProvider -> AuthenticationManager -> AuthenticaitonFilter)

하지만 ID 인증실패 or Password 인증에 실패했다면 AuthenticationFilter로 돌려보내서 실패처리를 하게됨

PasswordEncoder :

사용자가 입력한 패스워드와 암호화 된 패스워드를 matches메서드를 이용해서 일치 여부를 확인함 이때 암호화된 패스워드는 절대 디코딩 하지 않음

UserDetailsService :

AuthenticationProvider가
아이디 Password 검증시 실제로 UserInfo가 DB에 저장되니까
쿼리를 날려서 DB에 해당 ID를 가진 유저가 있는지를 데이터 객층에 질의 할때 이 타입의 클래스를 사용함 이때 존재한다면 User객체를 하나 반환
여기서 검증하는건 ID만임 여부만 확인함

이때 당연하게 해당 User의 Info(ID, PASSWORD등 정보)를 담아서 반환해줌

ID검증 성공시엔 UserDetails객체를 역순으로 AuthenticationProvider까지 반환 (UserDetails -> UserDetailsService -> AuthenticationManagerAuthenticationProvider)

UserDetails:

UserDetailsService가 User존재 여부를 확인하고 존재시 반환하는 객체의 타입임

SecurityContext :

인증에 성공해 최종적으로 반환된 Authentication(해당 객체에 UserDetails 객체도 포함됨)를 AuthenticaitonFilter로 부터 전달받아서 저장

SecurityContext는 Spring에서 전역적으로 어디에서든 꺼내서 참조가가능하기 때문에 인증을 받았다는 보증을 해줌

Authorization 계층

ExceptionTranslationFilter :

인증(Authentication) or 인가(Authorization) 예외가 발생하게 되면 해당 필터에서 예외를 처리함 FilterSecurityInterceptor를 호출함

FilterSecurityInterceptor :

일반적으로 FilterChainProxy가 제일 마지막에 호출하는 필터로
인가에 대해 권한이 있는지 없는지 최종적으로 판단

해당 필터는 AccessDecisionManager와 AccessDecisionVoter 클래스를 가지고 있음

AccessDecisionManager :

해당 클래스가 접근을 허가할 것인지 허가하지 않을것인지 판단함

투표 결과를 최종적으로 판단해서 사용자가 서블릿으로 가게 할것인지
인증 페이지로 이동할 것인지 접근이 허가되지 않았다고 메시지를 표현할지 처리해줌

AccessDecisionVoter :

현재 사용자가 접근하고자 하는 자원에 권한이 있는지 없는지를 투표함

int ACCESS_GRANTED = 1;(허가)
int ACCESS_ABSTAIN = 0;(고려)
int ACCESS_DENIED = -1;(거부)

해당 투표 결과를 AccessDecisionManager에게 전달


그래서 OAuth2는 기본Security랑 뭐가 다른건대?

이 내용은 Spring Security의 기본적인 흐름이지만
OAuth2도 비슷한 흐름을 따름
하지만 OAuth2에 관한 필터를 사용해서도 인증객체(Authentication)를 반드시 만듬

AuthenticationManager도 이름이나 약간의 변경만 줘서 사용

해당 인증에 필요한 Provider도 사용하는 경우 존재함

따라서 이런 흐름들은 OAuth2역시 비슷하게 사용함

예외처리 권한관리 필터(ExceptionTranslationFilter, FilterSecurityInterceotor) 역시 사용함


출처

스프링 시큐리티 OAuth2 - Spring Boot 기반으로 개발하는 Spring Security OAuth2(https://www.inflearn.com/course/%EC%A0%95%EC%88%98%EC%9B%90-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0/dashboard)

profile
어제보다 개발 더 잘하기 / 많이 듣고 핵심만 정리해서 말하기 / 도망가지 말기 / 깃허브 위키 내용 가져오기

0개의 댓글