oauth2Client() - Resource Owner Password

스프링 시큐리티의 oauth2Login() 필터에 의한 자동 인증 처리를 하지 않고 DefaultOAuth2AuthorizedClientManager 클래스를 사용하여 Spring MVC에서 직접 인증처리를 하는 로그인 기능을 구현한다.

기본 구성

  • AppConfig : DefaultOAuth2AuthorizedClientManager 빈 생성 및 설정 초기화

  • DefaultOAuth2AuthorizedClientManager : OAuth2 권한 부여 흐름 처리

  • LoginController : DefaultOAuth2AuthorizedClientManager를 사용해서 로그인 처리

로그인 구현 순서

  1. DefaultOAuth2AuthorizedClientManager 빈 생성 및 파라미터 초깃값 정의

  2. 권한 부여 유형에 따라 요청이 이루어지도록 application.yml 설정 조정

  3. /oauth2Login 주소로 권한 부여 흐름 요청

  4. DefaultOAuth2AuthorizedClientManager 에게 권한 부여 요청

  5. 권한 부여가 성공하면 OAuth2AuthenticationSuccessHandler를 호출하여 인증 이후 작업 진행

    • DefaultOAuth2AuthorizedClientManager의 최종 반환값인 OAuth2AuthorizedClientOAuth2AuthorizedClientRepository에 저장

  6. OAuth2AuthorizedClient 에서 AccessToken을 참조하여 /userinfo 엔드포인트 요청으로 최종 사용자 정보를 가져온다.

  7. 사용자 정보와 권한을 가지고 인증객체를 만든 후 SecurityContext에 저장하고 인증 완료

  8. 인증이 성공하면 위 과정을 커스텀 필터를 만들어 처리하도록 한다.

img_17.png
img_18.png

예제 코드

application.yml

AppConfig

여기서 정의한 contextAttributesMapper() Function 인터페이스로 PasswordOAuth2AuthorizedClientProvider 에서 OAuth2PasswordGrantRequest를 생성하여 인가 서버에 요청하게 된다.

이렇게 하기 위해서는 컨트롤러에서 OAuth2AuthorizeRequestHttpServletRequest 객체를 담아야 파라미터를 추출할 수 있다.

👏 참고 - DefaultOAuth2AuthorizedClientManager 생성자

img_19.png
  • 기본적으로 DefaultOAuth2AuthorizedClientManager 셍성자 만으로 모든 필요한 필드값들은 초기화가 된다.

  • 커스텀이 필요할 때 setter()를 통해 커스텀 할 수 있다.

img_20.png
  • 기본 ContextAttributes는 다음과 같다. 파라미터에 scope 값만 속성에 추가해준다.

  • Resource Owner Password 방식에서는 usernamepassword가 필요하기 때문에 커스텀 해 주었다.

img_21.png

HTML

LoginController

과정 디버깅

1. 컨트롤러

  • 익명 인증 객체, request 등을 포함한 OAuth2AuthorizeRequest를 생성하고 DefaultOAuth2AuthorizedClientManager를 호출한다.

img_22.png

2. DefaultOAuth2AuthorizedClientManager

  • 이미 인증 받은 클라이언트가 있는지 확인한다.

  • 현재는 처음 요청이기 때문에 clientRegistration 정보를 담은 OAuth2AuthorizationContext를 생성한다.

img_23.png
  • 추가로 필요한 속성들을 저장한다.

  • 여기서 설정 클래스에서 만든 Function이 실행된다.

img_24.png
img_25.png
  • 최종 생성된 OAuth2AuthorizationContextauthorizedClientProvider에게 전달한다.

img_26.png
img_27.png

3. DelegatingOAuth2AuthorizedClientProvider

  • OAuth2AuthorizedClientProviderBuilder에 의해 생성된 각 OAuth2AuthorizedClientProvider에게 요청을 위임한다.

img_29.png
img_28.png

4. PasswordOAuth2AuthorizedClientProvider

  • 권한 부여 타입, 필수 속성, 이미 authorizedClient가 존재하고 AccessToken이 만료되지 않았는지, AccessToken은 만료되고 RefreshToken이 존재하는지 확인한다.

img_30.png
  • 첫 요청이기 때문에 어느 것도 해당되지 않아 인가 서버와 통신한다.

  • DefaultPasswordTokenResponseClient에게 인가 서버 통신을 맡긴 후 받은 결과로 OAuth2AuthorizedClient를 반환한다.

img_31.png
img_32.png

5. DefaultPasswordTokenResponseClient

  • 인가 서버와 통신 후 OAuth2AccessTokenResponse를 반환한다.

img_33.png

6. DefaultOAuth2AuthorizedClientManager

  • authorizationSuccessHandler를 실행하고 authorizedClient를 반환한다.

img_34.png
  • 그리고 나서 다시 컨트롤러에서 DefaultOAuth2UserService로 사용자 정보를 얻고 최종 인증 객체를 SecurityContext에 저장한다.

img_36.png
img_35.png

이전 ↩️ - OAuth 2.0 Client(oauth2Client) - DefaultOAuth2AuthorizedClientManagerarrow-up-right

메인 ⏫arrow-up-right

다음 ↪️ - OAuth 2.0 Client(oauth2Client) - DefaultOAuth2AuthorizedClientManager - Client Credentials 권한 부여 구현arrow-up-right

Last updated