ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring boot 2.x 와 Spring security Oauth2 연동
    spring/security 2021. 4. 21. 20:05

    배경

    진행 중인 프로젝트는 SSO(Single Sign On) 방식을 지원하지 않는다. 어떤 사용자든 서비스를 이용하기 위해서 신규회원으로 가입해야 한다. 네이버 로그인을 지원해 사용자의 편의성을 높여보자.

     

    docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login-sample-boot

    위 내용을 참고 및 공부하는 내용이다.

     

    큰 그림

    - 유저는(Resource Owner) 서비스서버에게(Client) OAuth2.0방식 로그인을 요청한다.

    - 서비스서버는 유저를 몇몇 정보와 함께 인증서버로(Service API) 리다이렉트한다.

    - 유저는 인증서버에서 인증을 진행한다.

    - 인증서버는 유저를 서비스서버의 callbackURL로 옮기면서 Authorization Code를 넘긴다.

    - 서비스서버는 Authorization Code를 다시 인증서버에게 넘긴다

    - 인증서버는 Authorization Code의 유효성을 검사한 뒤 서비스서버에게 accessToken을 전달한다.

    - 서비스서버는 accessToken과 함께 유저의 정보를 DB에 저장한다.

     

    네이버 아이디로 로그인 정보 생성하기

    developers.naver.com/apps/#/register

     

    애플리케이션 - NAVER Developers

     

    developers.naver.com

    등록 과정에서 서비스URL은 http://localhost:8080으로 Callback URL은http://localhost:8080/login/oauth2/code/naver로 등록하자. 자세한 설정은 나중에 위 URL을 사용할 때 설명! 등록을 통해 ClientID와 Client Secret를 얻도록 하자.

    The default redirect URI template is {baseUrl}/login/oauth2/code/{registrationId}. The registrationId is a unique identifier for the ClientRegistration.

     

    application.yml 설정하기

     

     

    CommonOAuth2Provider 알고 가기

    네이버아이디로그인(네아로) 시 거의 모든 블로그에 네이버는 스프링이 지원하지 않아서...와 같은 내용을 봤다. 위 공식 문서 내용이 모든 걸 설명해준다. 즉, Google, GitHub과 같은 굉장히 유명한 오픈 API는 기본적으로 제공해주는 OAuth2Provider가 있고 그 ID만 yml에 등록해줘도 알아서 Provider가 등록된다는 내용이다. 다만, client id와 secret는 필수로 적어줘야 한다. 네아로를 이용하기 위해선 Provider를 내가 만들어서 등록해줘야 한다는 사실을 추측할 수 있다. 일단 GOOGLE이 Provider로 등록된 걸 확인해보자.

    oauth2-client를 추가하면서 이런 enum이 추가된 걸 확인할 수 있다.

     

     

    네이버로 설정한 ClientRegistration 등록하기

    위와 같이 Provider를 통해 ClientRegistration을 만들어 등록할 수 있지만 예제가 직접 ClientRegistration을 만들어 등록했으므로 동일하게 등록하겠다.

     

    - 커스터마이징한 ClinetRegistration이 @Configuration과 @Bean을 통해 빈으로 등록했다.

    - clientId와 clientSecret로 네아로가 내 애플리케이션을 식별한다

    - redirectUri를 지정해서 클라이언트가 네이버로 로그인한 뒤 내 애플리케이션으로 돌아올 URL을 지정한다

    - authorizationGrantType는 인증토큰 발급 전 진행하는 인증 방식을 CODE로 하겠다는 의미다.(가장 보편적)

    - userNameAttributeName으로 ...

     

     

    OAuth2AuthorizationRequestRedirectFilter 확인

    기본으로 등록되는 필터이며 이 필터가 최소 사용자가 네이버로그인을 시도했을 때 처리하는 역할을 한다.

    프런트에서 <a href=".../oauth2/authorization/naver"/> 이런 식으로 하면 된다.

    이 필터를 통해 위에서 설정한 https://nid.naver.com/oauth2/authrization?... 로 사용자는 이동하게 된다.

     

     

    OAuth2LoginAuthenticationFilter 확인

    네이버 로그인을 마친 뒤 네이버는 사용자를 callbackUri로 보내게 된다. 그리고 이 필터가 작동하게 된다.

    네이버는 서버로 두 파라미터를 담아 보내는데 code를 주목해야 한다. 이 code를 가지고 네이버에게 accessToken을 받아와야 한다. 여기서 디버깅하는 데 시간이 오래 걸렸다. code를 받은 요청에서 응답으로 당연히 새로운 요청을 nid.naver.com/oauth2/token?code=..으로 요청할줄 알았다. 그런데 이 하나의 필터에서 code를 받고 accessToken까지 받아오는 상황이 벌어진 것이다. 설마 accessToken을 현재 서버에서 만드나하는 말도 안되는 의심을 했고 깊게 디버깅하면서 답을 찾았다.

     

    끝까지 쫓아가면 요청을 전환하는 코드를 볼 수 있다. 내부적으로 RestTemplate을 사용해 새로운 요청을 보내고 응답 값을 받는 걸 확인할 수 있다. 이렇게 내부적으로 추가적인 http통신이 일어나는 것이다! (근데 생각해보면 이상할 것도 없는게 DB통신이 다 이런 거 아닌가..?)

     

    여튼 토큰생성과 이를 저장하며 객체를 반환함으로써 작업을 마치는 걸 볼 수 있다.

     

     

    회원 DB에 추가하기

    애플리케이션 회원과 SSO방식으로 가입한 회원을 구분해서 설계하는 건 일단 미루도록하자. 인증서버의 동일한 회원에게는 동일한 accessToken이 발급되니 이제 이 회원을 회원가입하도록 하자. 간단하게 OAuth2AuthorizedClientService를 구현한 클레스를 빈으로 등록하기만 하면 된다. 내부적으로 위 타입 빈이 없는 경우에만 디폴트 인메모리 서비스를 사용한다.

     

    코드를 보면 직관적으로 이해할 수 있을 정도로 간단하게 작성했다. 여기까지 작업을 마치고 간단하게 테스트를 진행하면 원하는 대로 DB에 회원이 저장된 걸 확인할 수 있다.

     

     

    마치며

    부족한 내용이 굉장히 많지만 어느정도 OAuth2.0의 흐름을 이해할 수 있었다. google, github로그인은 적용하긴 쉽지만 흐름을 알기에는 너무 추상화되어 있어 네이버로 적용했다. 여기서 jwt토큰 추가 및 사용자DB설계까지 진행해보면 더욱 많은 공부가 될 것 같다.

     

    'spring > security' 카테고리의 다른 글

    Spring Security에서 CORS 해결  (0) 2021.03.24
    SecurityContextHolder의 역할 및 원리  (0) 2021.03.03
    Spring Security 아키텍처  (0) 2021.02.21

    댓글

Designed by Tistory.