공부하고 기록하는, 경제학과 출신 개발자의 노트

프로그래밍/이것저것_개발일지

화상 모의면접 연습 플랫폼 개발 프로젝트 (2) - KeyCloak 활용해서 서비스 DB에 OAuth 인증 붙이기

inspirit941 2021. 4. 18. 18:35
반응형

Yapp 동아리의 개발 프로젝트였던 화상 모의면접 연습 플랫폼 "위더뷰" 개발에 백엔드 개발자로 중도 합류했다.
 
github.com/witherview/witherview_backend

witherview/witherview_backend

🎯 위더뷰 Backend. Contribute to witherview/witherview_backend development by creating an account on GitHub.

github.com

기본적으로는 자바 스프링부트를 사용하지만, WebRTC의 경우 Node JS를 사용하는 구조다. 프론트는 React 기반이다.
중도에 합류해서 기존 코드와 구조를 어떻게 분석했는지 / 어떻게 개선방안을 찾아갔는지 생각을 정리하는 용도의 포스트.
 


 
이 당시 서비스 백엔드는 서버 메모리에 세션을 저장하는 방식의 로그인을 사용하고 있었다.
Spring에서 세션 방식의 로그인 구현이 쉬운 건 맞지만, 세션 기반 방식에서 토큰 기반 방식으로 변경하려 했던 이유는 두 가지였다.

  • 서버 메모리에서 사용자의 세션을 관리하는 방식은 scale out을 시도하기 어려운 구조.
  • Stateful한 구조. 서버가 일시적으로 다운되면 로그인 정보가 초기화될 수 있음.

이외에도 찾아보면 토큰 기반 로그인이 좋은 이유가 여러 개 나오지만,
웹에서 보편적으로 쓰는 stateless 방식 대신 stateful을 유지해야 할 이유가 딱히 없기도 했다.
 

 
사용자 인증을 위한 서비스로는 Keycloak 오픈소스를 활용해서 별도의 인증서버를 구축하기로 했다.

  • Java based 프로젝트이므로, Spring으로 만든 우리 API 서버와 코드 레벨에서 로직을 연동하기 쉬울 것이라고 판단했음.
  • KeyCloak에서 제공하는 OAuth 기능을 활용할 수 있고, JWT 토큰도 발급받을 수 있음.
  • Storage Provider Interface를 사용하면, 별도의 DB migration 없이 KeyCloak 서버를 인증에 사용할 수 있음.

 


구상

udemy의 OAuth 2.0 in Spring Boot Application 강의 스크린샷

위의 스크린샷은 참고용이며, 실제로 구상한 flow는 스크린샷과 약간 다르다.

  • 서비스 API의 User 데이터베이스는 그대로 유지한 채,
    클라이언트가 로그인 요청을 Existing Spring Boot Web Service로 보낸다.
  • Spring Boot Web Server는 로그인 요청을 받으면, KeyCloak Server에 Authentication 요청을 보낸다.
  • KeyCloak Server는 ID와 Password의 Valid 여부를 체크해서, 정상일 경우 JWT 토큰을 서버로 반환한다.
  • 사용자가 JWT 토큰을 포함해서 API 서버에 request를 보내면,
    KeyCloak Server를 구성할 때 사용한 정보 (client-id, client-secret, realm 등)를 토대로 JWT 토큰을 파싱한다.

 

적용

KeyCloak에서 사용할 RemoteUserStorageProvider 클래스를 생성하고, 세 개의 인터페이스의 구현체를 implement한다.

  • UserStorageProvider: KeyCloak의 Storage Provider Interface 구현을 위한 기본 인터페이스.
  • UserLookUpProvider: remote storage에서 userDetail을 조회하기 위한 용도
  • CredentialInputValidator: User Credential을 검증하기 위한 용도

 

다음으로, RemoteUserStorageProviderFactory 클래스를 생성한다.
 
 

RemoteUserStorageProviderFactory에서 External Web Service에 유저 정보 확인을 위해 호출할 API 명세를 지정한다.
여기서 호출할 API path와 payload는 Web Service Controller에 똑같이 지정한다.
https://github.com/witherview/witherview_backend/blob/bd21e0386c780fc1fb4e5dde1741292e2acfad6a/account-api/src/main/java/com/witherview/account/controller/AccountController.java#L227

GitHub - witherview/witherview_backend: 🎯 위더뷰 Backend

🎯 위더뷰 Backend. Contribute to witherview/witherview_backend development by creating an account on GitHub.

github.com

 
 
커스텀하게 생성한 UserStorageProvider를 KeyCloak에 등록하려면, jar 파일로 패키징해야 한다.
UserStorageProvider를 정의한 SpringBoot 프로젝트의 resource 하위 디렉토리에 META_INF/services 를 생성하고, 아래와 같이 파일을 생성한다.

UserStorageProviderFactory 클래스가 정의된 패키지명을 정확히 입력한 뒤,
UserStorageProvider SpringBoot 애플리케이션을 jar 파일로 빌드한다.
 

배포

https://www.keycloak.org/downloads.html 에서 keycloak zip파일을 다운받는다. 

downloads - Keycloak

Downloads 21.0.2 For a list of community maintained extensions check out the Extensions page. Server Quickstarts Client Adapters WildFly [DEPRECATED] <= 23 ZIP (sha1) TAR.GZ (sha1) JBoss EAP [DEPRECATED] 7 ZIP (sha1) TAR.GZ (sha1) JavaScript Node.js [DEPRE

www.keycloak.org

standalone/deployment 디렉토리에 빌드한 jar 파일을 복사한다.
 

UserStorageProvider가 정상적으로 설정되었다면,
keycloak 서버가 실행중인 상태에서 jar 파일을 복사해넣었을 때 HUD Deployment가 수행된 결과 파일이 생성된다.
위 스크린샷의 경우 *.jar.deployed 파일이 생성되면 정상적으로 해당 UserStorageProvider가 keycloak에 배포된 것.
 
 

keycloak UI에서 User Federation을 확인했을 때, Custom UserStorageProvider package명이 확인되고
Enable 설정하면 UserStorageProvider를 적용할 수 있다.
 


KeyCloak에서 생성하는 JWT Token에 custom Field를 추가할 수도 있다. 방법은 아래 링크를 참고했음
https://github.com/mschwartau/keycloak-custom-protocol-mapper-example/blob/master/README.md

GitHub - mschwartau/keycloak-custom-protocol-mapper-example: An example for building custom keycloak protocol mappers

An example for building custom keycloak protocol mappers - GitHub - mschwartau/keycloak-custom-protocol-mapper-example: An example for building custom keycloak protocol mappers

github.com

 
https://github.com/mschwartau/keycloak-custom-protocol-mapper-example/tree/master/protocol-mapper

GitHub - mschwartau/keycloak-custom-protocol-mapper-example: An example for building custom keycloak protocol mappers

An example for building custom keycloak protocol mappers - GitHub - mschwartau/keycloak-custom-protocol-mapper-example: An example for building custom keycloak protocol mappers

github.com

 
 

반응형