OAuth2AuthorizedClientRepository를 사용해서 OAuth2AuthorizedClient를 저장 후 클라이언트의 Redirect Uri로 이동한다.
실행 조건
요청 파라미터에 code와 state 값이 존재하는지 확인
OAuth2AuthorizationRequest 객체가 존재하는지 확인
img_8.png
예제 코드
Controller
HTML
yml
과정 디버깅
1. OAuth2AuthorizationRequestRedirectFilter
사용자 승인을 할 수 있는 url로 리다이렉트 한다.
img_9.png
2. OAuth2AuthorizationCodeGrantFilter
리다이렉션 되어 이 필터로 왔다.
특정 조건에 만족하면 특정 처리를 하고 다음 필터로 가지 않고, 만족하지 않으면 다음 필터로 넘어간다.
img_10.png
요청 파라미터에 code와 state가 존재하는지 보고, OAuth2AuthorizationRequest가 존재하는지 확인한다.
img_11.png
img_12.png
redirect_uri를 비교한다.
img_13.png
모든 조건을 만족하면 다음 코드를 실행한다.
먼저 AuthenticationManager(ProviderManager)에게 인증 요청을 위임한다.
여기서 사용되는 AuthenticationProvider는 OAuth2AuthorizationCodeAuthenticationProvider로 여기서 인가 서버와 통신하여 Access Token 교환이 이루어진다.
img_14.png
그리고 OAuth2AuthorizedClient를 저장하고, redirectUrl로 리다이렉트 한다.
여기서 redirectUrl은 application.yml 파일에서 설정한 경로이다.
img_15.png
3. controller
그리고 나서 스프링 MVC로 넘어온다.
여기로 리다이렉션 되어 요청이 왔다는 것은 클라이언트가 인가 서버로부터 인가를 받은 상태에서 온 것이다.
하지만 최종 사용자의 인증 처리가 된 것은 아니기 때문에 SecurityContextHolder 에서 꺼낸 Authentication은 아직 "Anonymous" 이다.
그래서 DefaultOAuth2UserService에게 UserInfo 엔드포인트 요청을 보내 사용자 정보를 얻고 SecurityContextHolder에 저장해 주었다.
참고로 기본으로 빈으로 등록되는 OAuth2AuthorizedClientRepository 구현체는 익명 사용자이더라도 principalName을 anonymousUser로 해서 반환하지만 OAuth2AuthorizedClientService 구현체는 그렇지 않기 때문에 null이다.