
[Oauth2 Filter 흐름 및 이해]
이 포스팅을 보기전
[스프링 시큐리티 Oauth2.0] Oauth2.0 동작방식 (tistory.com)
[스프링 시큐리티 Oauth2.0] Oauth2.0 동작방식
[소개] Oauth2를 사용하기 위해서 Oauth의 흐름을 알아보도록 한다. [Oauth2 사용자] Oauth의 경우 총 4명의 사용자들을 정의 할 수 있다. ● Resource Owner(사용자) : 일반적으로 사용자를 가르키며 소셜 서
thaud153.tistory.com
이 Oauth2의 동작이 어떤식으로 이루어지는지 보고 오길 바란다.
1. Authorization Code 요청 하기
● code를 요청하는 방식에는 두 가지 방식이 있다.
1. 프론트에서 요청 후 백엔드에게 전송
이 방식을 사용한다면 백 채널에서는 코드를 받는 필터는 동작하지 않게 되고
프론트에서 코드를 받은 순간 필터가 작동한다.
2. 백엔드에서 코드를 요청 후 리다이렉트 경로로 코드를 받음.
이 방식은 백엔드 자체에서 코드를 발급 요청을 한 후 리다이렉트 경로를 이용해서
코드를 받은 후 처리한다.
우리는 2번째 방식에 대해 알아볼 것 이다.
1. 사용자에게 oauth2 화면을 보여준다

2. 경로
naver,google,kakao와 같은경우
/oauth2/authorization/code/google
/oauth2/authorization/code/naver"
"/oauth2/authorization/code/kakao"
이러한 기본경로를 가지고있다.
이 경로의 의미는 oauth2.authorization/code/{registerationId}
가 들어온다면

Oauth2AuthorizationRequestRedirectFilter가 동작하게 된다.
인터셉트의 조건은 oauth2/authorization/code/{registertionId}의 경로로 들어오면
이 필터가 시작되고 이 필터가 구글혹은 네이버등의 인증창을 리다이렉트 시켜서
사용자에게 구글 인증을 보이게 하는 필터이다.

code는 이러한 방식으로 필터체인이 동작하는데
1. 사용자가 oauth2/authorization/{registrationId} 링크로 들어온다
● Oauth2AuthorizationRequestRedirectFilter가 oauth2/authorization/code/{registerationId}로 들어오게 된다면
인터셉트를 하여 이 경로로 들어온 사용자를 해당 인증 페이지로 리다이렉트 시킨다
2. DefaultOauth2AuthorizationRequestResolver
● 사용자를 인증 서버 (구글 로그인)로 리다이렉트 하기전 Oauth2AuthorizationRequest 객체를 생성하는
역활을 한다.
● 즉 이클래스는 인증 서버로 보낼 인증 요청을 구성하는데 사용된다.
●요청 매칭 들어오는 요청이 oauth2/authorization/{registrationId}와
같이 oauth2를 시작하는데 사용되는 URL 패턴과
일치하는지 확인한다.
●Oauth2AuthorizationRequest 생성
● 일치하는 요청을 발견한다면 이 클래스는 해당 요청에 기반하여 Oauth2AuthorizationRequest 객체를 생성한다.
● 이 객체에는 인증 요청에 필요한 모든 정보가 포함된다.
● client_ id : 인증을 요청하는 클라이언트 id임.
●redirct_uri : 인증 후 사용자를 리다이렉할 클라이언트 url
●scope : 클라이언트가 요청하는 권한의 범위
●state : CSRF 공격으로부터 보호하고 인증 요청과 응답 사이의 연속성을 유지하기 위한 값
--------------------------------------------------------------------------------
● 인증 URL 구성 : 위의 정보를 사용하여 사용자를 인증 서버 URL 리다이렉트할 준비를 한다.
●리다이렉트 실행
oauth2AuthorizationRequestRedirctFilter가 이 oauth2AuthorzationRequest를 사용하여 사용자를
실제 인증서버로 리다이렉트 한다.
3. Maches가 yes인 경우
● DefaultOauth2AuthorizationRequestResolver가 생성한 Oauth2AuthorizationRequest가
현재 들어온 인증 정보와 같은지 비교함.
즉 사용자가 처음에 요청한 인증 정보와 인증 서버로부터 리디렉션될 요청의 정보와 일치하는지
확인하는 과정임.
이 맥락에서 "일치한다"라는 것은 사용자가 인증을 요청할 때 사용한 {registerationId} -> 구글 네이버 카카오 등
이 서버로 돌아온 요청의 정보와 같다는 의미임.
4. action : /login
● {action}/oauth2/code/{registrationId}
-> 여기에 적힌 url 경로는 우리가 properties에서 설정한 url 경로임.
● 시큐리티가 이 경로를 요청하게되고 시큐리티는 Oauth2AuthorizationRequest에서 들어있는 값의 정보를
HttpSessionOauth2AuthorizationRequestRepository에 Oauth2AuthorizationRequest의 객체를 저장한다.
● HttpSessionOauth2AuthorizationRequestRepository는 Oauth2AuthorzationRequest객체를
저장한다.
● sendRedirct
● client_id , response_type , state , redirect_url등이 저장된 Oauth2AuthorzationRequest를
인증서버로 전송한다.
●인증서버에 정상적으로 요청을 하였다면 인증 서버에서 액세스 토큰과 바꾸기 위한
code를 발급한다.
여기까지가 code발급이다. 해당 code발급은 보통은 프론트에서 진행하게 되며
프론트에서 code를 백엔드 채널로 주는 경우가 보통이다.
[Code를 받은 후 -> AccesToken 요청]

1. 코드를 받은 후 인증서버는 프로퍼티스에 저장되어 있는 redirct_url 경로로 리다이렉트 시킨다.
리다이렉트 경로는 /login/oauth2/code/{registrationid}이다.
2. /login/oauth2/code/{registrationid}
● 이 경로로 들어오게 되면 Oauth2LoginAuthenticationFilter가 받게 된다.
3. HttpSessionOauth2AuthorizationRequestRepository
●인증을 시작할 때 생성된 Oauth2AuthorizationRequest를 저장하는 저장소이다.
●이 저장소는 HTTP 세션을 사용하여 인증 요청을 저장하며 , 나중에 인증 요청을 나타내는 객체이다.
●위에서도 설명했다싶이 인증 서버로부터 리다이렉를 받을 때 필요한 정보들이 들어있다.
4.Oauth2AuthorizationResponse
● 인증 서로부터 응답을 나타내는 객체이다.
●이 객체는 리다이렉션 후에 상태 등이 포함되어있다.
5. Oauth2LoginAuthenticationToken
● 이 토큰에는 인증코드 , 클라이언트 정보(클라이언트 id , 시크릿 번호)를 담아
Oauth2AuthorizationCodeAuthenticationProvider에 전달한다.
즉 이 객체는 인증 코드를 액세스 토큰으로 교환하는데 필요한 정보를 담고 있는 토큰이며
"미인증"상태로 사용된다.
그리고 나서 , 액세스토큰을 받아 사용자 인증을 완료하면 토큰은 "인증" 상태로 바뀌며
사용자의 인증 정보를 애플리케이션 내에서 참조할 수 있음.
6.OAuth2AuthorizationCodeAuthenticationProvider
● 인증 코드를 액세스 토큰으로 교환하는 과정을 처리하는 객체이다.
● 인증 코드 검증 : 사용자로부터 받은 인증 코드가 유효한지 확인한다.
7. RestTemplate -> ResponseEntity
● 액세스 토큰 요청
● Oauth2.0 액세스 토큰으로 교환하기위 인증 서버 엔드포인트 (/token)으로 post요청을 보낸다.
● 이 요청은 필요한 모든 파라미터를 포함하며 , client_id , clint_secret ,code ,grant_type ,redirct url
등이 포함된다.
● 요청 엔티티 구성 : RestTemplate은 RequestEntity 객체를 사용하여 요청 본문 , 헤더 ,
Http 메서드 , URL등 요청에 필요한 정보를 구성한다.
● RequestEntity는 RestTemplate에 의해 엔드포인트로 보내지게 되고 이 요청을 받은 객체가
ResponseEntity가 된다.
8. ResponseEntity
● 비로소 액세스 토큰을 받게 되었다.
● 이 객체는 일반적으로 json 형태로 액세스 토큰과 관련된 (access_token , token_type , expires_in ,
refresh_token ,scope의 정보들을 가지고있다)
● Http 상태코드
● 요청이 성공적이였는지 에러가 발생했는지의 여부의 상태를 저장하는 상태코드를 가지고있다.
9. Oauth2AuthorizationCodeAuthenitcationToken
● 비로소 이 토큰은 "미인증" 상태에서 "인증"상태로 바뀌게 된다.
● 인증 후
●인증 서버로 부터 액세스 토큰을 성공적으로 받았다면 이 객체는
access token,refresh token등을 포함하게 된다.
● 즉 이 객체는 초기에는 액세스 토큰과 리프레쉬 토큰을 포함하지 않지만
인증 과정을 완료하고 난 후 이 액세스 토큰을 포함하게 되며 인증된 사용자를 나타나는데 사용된다.
● 이렇게 변환된 토큰은 OAuth2AuthenticationToken불린다.
10. Oauth2Request
● 이 객체는 Oauth2.0 인증 프로세스 중 액세스 토큰을 교환한 후 생성 된다.
● 액세스 토큰
사용자가 인증 서버로부터 받은 액세스 토큰을 가지고있다.
● 등록된 클라이언트 정보
Oauth2UserRequest는 Oauth2 클라이언트 구성 정보를 포함한다.
이는 ClientRegistration 객체에 의해 나타내어지며
클라이언트 id , 시크릿 , 인증 방법 , 토큰 url등이 포함되어있다.
● 이 객체는 DefaultOauth2Service 일 때 매개변수 값으로 들어오게 되며
DefaultOauth2Service의 반환 값은 Oauth2User가 된다.
11. DefaultOauth2Service
●이 객체는 Oauth2UserRequest의 매개변수 값을 받으며
이 받은 객체를 바탕으로 DefaultOauth2Service에서 DB와 연결한 후 사용하는 것이 일반적이다.
--------------- ---------------------------------
여기까지가 액세스 토큰을 가져오는것이고
유저의 정보를 가져오는 것은 매우 간단한다.
DefaultOauth2Service의 클래스에
@Override
//여기에 들어오는 userRequest 액세스토큰과 , 코드등이 들어있음 유저 정보는 X
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
ClientRegistration clientRegistration = userRequest.getClientRegistration();
OAuth2UserService<OAuth2UserRequest,OAuth2User> oAuth2UserService
= new DefaultOAuth2UserService();
//이 메서드 호출로 유저의 정보를 가져옴.
//이 메서드 호출로 oauth2User에는 유저 정보가 들어있음.
OAuth2User oAuth2User = oAuth2UserService.loadUser(userRequest);
이러한 클래스가 있다.
oauth2UserService.loadUser(userRequest)를 넣으면
시큐리티에서 액세스토큰을 기반으로 유저 정보를 가져오는데
유저 정보의 담긴 객체 이름이 Oauth2User이다.
'스프링 시큐리티 -세션 > Oauth2.0' 카테고리의 다른 글
| [스프링 시큐리티] Oauth2 구현방법 및 흐름 (0) | 2024.01.31 |
|---|---|
| [스프링 시큐리티 Oauth2.0] Oauth2.0 동작방식 (0) | 2024.01.19 |