Spring - OAuth2.0 Login 기본 flow

Tadap·2023년 9월 12일
0

Spring Security

목록 보기
2/7

OAuth2.0Login을 선언하고 몇가지 설정만 해주면 된다.

OAuth2LoginConfigurer

먼저 SecurityFilterChain을 구성해 주고
그 안에 oauth2Login을 설정해주면 내부에서 OAuth2LoginConfigurer가 실행이 된다.

2가지 매서드가 호출되는데 initconfigure이다.

init

먼저 OAuth2LoginAuthenticationFilter로 기본 url은 /login/oatuh2/code/*로 요청이 오면 이걸 처리한다. * 은 google, github 등 provider이다.
이를 통해서 AccessToken을 교환하고 사용자 정보 엔드 포인트 요청을 필터한다.

다음으로 OAuth2LoginAuthenticationProvider로 위 OAuth2LoginAuthenticationFilter 가 요청을 Provider로 위임을 한다.

나머지 하나는 OidcAuthorizationCodeAuthenticationProvider이다.
OAuth2LoginAuthenticationProvider는 OAuth2.0이고 해당 Provider는 OIDC를 이용한다.

OAuth2LoginAuthenticationFilter 에서 들어오는 요청 처리
처리 방식으로 OAuth2.0, OIDC가 있다.
둘다 accessCode를 accessToken으로 교환하고, 바꾼 토큰으로 유저 정보를 가져온다.

configure

configure에서는 OAuth2AuthorizationRequestRedirectFilter가 있다.
이 필터는 임시코드 발급 엔드 포인트 요청 필터이다.
OAuth2.0 flow를 따라서 보면, 먼저 accessCode를 받고 이를 accessToken으로 교환을 하는데
여기서는 accessCode를 받는 역할을 한다.
이 필터가 동작하기 위한 조건 url은 /oauth2/authorization/{registrationId}이다.

OAuth2.0 AccessCode요청

OAuth2LoginConfigurer 설정 속성

4가지 속성이 있다

  1. AuthorizationEndpointConfig
    accessCode 발급 요청시 필요한 정보 관련 설정
  2. RedirectionEndpointConfig
    인가서버 -> 클라이언트 리다이렉트시 정보 포함
  3. TokenEndpointConfig
    accessToken 발급 요청과 관련된 설정
  4. UserInfoEndpointConfig
    accessToken 을 이용해 정보 관련 설정

OAuth2.0 로그인 페이지

기본적으로 생성해 준다.
기본 생성시 OAuth2.0 클라이언트 이름을 보여주고 링크를 눌러 인가를 시작하는데
이때 Url은 /oauth2/authorization/{registrationId}이다.
이 기본 페이지 재정의는 oauth2Login().loginpage()를 사용한다.

주요 클래스

  1. OAuth2AuthorizationRequestRedirectFilter에서 브라우저를 통해 인가 서버의 권한 부여 엔드포인트로 리다이렉션 하여 권한 코드 부여 흐름을 시작한다.
    그중 /oauth2/authorization/{registrationId} 로 들어온 요청에 대해 시작하며
    AuthorizationEndpointConfig. authorizationRequestBaseUri를 통해 위 주소를 재정의 할 수 있다.
  2. DefaultOAuth2AuthorizationRequestResolver는 요청에 대해서 아래3.에 해당하는 객체를 완성한다.
    /oauth2/authorization/{registrationId} 링크로 들어온 요청에 대해 registrationId를 추출하고 해당하는 ClientRegistration을 가져와 OAuth2AuthorizatinoRequest를 만든다.
  3. OAuth2AuthorizatinoRequest는 Accesscode를 AccessToken으로 교환하기 위한 파라미터를 담고 있다.(요청 uri, clientId 등등)
    또한 검증시에도 사용한다.
  4. OAuth2AuthorizationRequestRepository는 인가요청 시작~리다이렉트(AccessCode받기)시점까지 OAuth2AuthorizationRequest를 유지합니다. (flow 진행중 데이터 임시 저장소라고 생각)

Request -> OAuth2AuthorizationRequestRedirectFilter -> DefaultOAuth2AuthorizationRequestResolver -> 접근권한이 없는 상태로 접근을 시도하면 OAuth2AuthorizationRequestRedirectFilter 를 다시 호출 -> /{action}/oauth2/code/{registrationId} 로(action에는 login이 들어감) -> OAuth2AuthorizatinoRequest -> OAuth2AuthorizationRequestRepository를 구현한 HttpSessionOAuth2AuthorizationRequestRepository에 요청정보 임시 저장 -> Redirect -> 사용자 인증 -> 정보 받음

미인증 상태로 접근시 -> Filter를 호출하여 인증하게 함
인증상태로 접근시 -> 정해진 flow를 따라감

OAuth2.0 AccessToken요청

주요 클래스

  1. OAuth2LoginAuthenticationFilter는 받은 code를 AccessToken으로 교환한다.
    받은 Token을 OAtuh2LoginAuthenticationToken으로 저장해서 AuthenticationManager에 위임해 UserInfo 정보를 조회하고 이를 통해 로그인 한다.
    OAuth2AuthorizedClientRepositoryOAuth2AuthorizedClient를 저장한다.
    인증 성공시 OAuth2AuthenticationToken이 생성되고 이를 SecurityContext에 저장한다.
    요청 Url은 `/login/oauth2/code/*'이다.

  2. OAuth2LoginAuthenticationProvider는 인가서버로부터 리다이렉트된 이후 AccessToken으로 교환하고, UserInfo 처리를 담당한다.
    만약 Openid가 포함되어있으면 OidcAuthorizationCodeAuthenticationProvider를 호출해 Oidc 처리를 하고 아니면 OAuth2AuthorizationCodeAuthenticationProvider를 호출해 제어한다
    OAuth2LoginAuthenticationProvider는 기본 OAuth2UserService를 가지는데 이 서비스는 인가서버와 직접 통신을 담당한다.
    1. OAuth2AuthorizationCodeAuthenticationProvider는 인가 서버로 부터 AccessToken의 교환을 담당한다. 교환 담당은 OAuth2AccessTokenResponseClient가 한다.
    2. OidcAuthorizationCodeAuthenticationProvider는 OIDC를 이용해 처리한다.

  3. DefaultAuthorizationCodeTokenResponseClient는 AccessToken을 받아 OAuth2AccessTokenResponse에 저장하고 반환한다. RestTemplate을 이용한다.

OAuth2LoginAuthenticationProvider 가 처리하는데
OIDC의 경우 OidcAuthorizationCodeAuthenticationProvider 가 처리하고 내부적으로 OidcUserService, DefaultOidcUser
아닌 경우 OAuth2AuthorizationCodeAuthenticationProvider 가 처리하고 내부적으로 DefaultOAuth2UserServiceDefaultOAuth2User를 가진다.
그리고 이 둘은 DefaultAuthorizationCodeTokenResponseClient를 인가 서버와 통신을 한다.

AccessToken 발급 정리

  1. State, Code 등 값을 받음(시작)
  2. redirect시 OAuth2LoginAuthenticationFilter에서 걸림
  3. HttpSessionOAuth2AuthorizationRequestRepository 에 임시 저장한 OAuth2AuthorizationRequest를 가져옴(AccessCode를 만들때 정보)
    그리고 서버에서 가져온 Code등의 정보는 OAuth2AuthorizationResponse에 있음(AccessCode를 AccessToken으로 바꾸기 위한 정보)
    이 두개의 정보를 OAuth2AuthorizationExchange에 담고 이걸 OAuth2LoginAuthenticationToken에 담는다.
  4. OAuth2LoginAuthenticationTokenProviderManger에게 보낸다.
  5. ProviderManager는 타입에 따라 맞는 Provider를 선택(여기선 OAuth2)
    따라서 순서대로 OAuth2LoginAuthenticationProvider -> OAuth2AuthorizationCodeAuthenticationProvider가 선택된다.
  6. Provider는 DefaultAuthorizatinCodeTokenResponseClient를 통해 RestTemplate으로 인가 서버와 통신을 한다.
  7. 통신 결과를 OAuth2AuthorizationCodeAuthenticationToken에 담는다.
  8. OAuth2UserRequest 가 사용자 정보를 인가서버로 부터 가져온다.
  9. DefaultOAuth2UserService가 정보를 가져온다.

0개의 댓글