SSO 구축기 - Authorization Server 선정과 프로필 서버 구축

김동균·2022년 11월 6일
4

SSO 구축기

목록 보기
2/3

본 포스팅은 SSO 구축기 시리즈의 2편이다.

1. Authorization Server 선정

SSO 구축을 위해 사용할 OAuth 2.0 Protocol에는 인증을 담당하는 Authorization Server가 있다.(자세한 내용은 1편 참고)
SSO를 위해 첫 번째로 해야 할 일은, Authorization Server를 구축하는 것이다.
당시 논의한 Authorization Server의 기준은 아래와 같았다.
1. SSO 지원
2. OAuth 2.0, OpenID Connect Protocol 지원
3. 빠른 구축
4. 무료 라이센스
5. 사용자 커뮤니티의 규모 및 꾸준한 업데이트, 높은 성숙도

위 내용들을 고려하여 리서치 한 결과, 아래와 같은 두 가지 후보가 도출되었다.

  • Spring Authorization Server를 사용하여 직접 구축
  • Keycloak (Open Source)

Spring Authorization Server는 Spring Security 프로젝트에 소속되어 개발되다가, 프로젝트가 중단된 이후 Spring Comnunity의 항의로 인해 2020년 4월 15일에 별도 프로젝트로 분리되어 개발되기 시작한 프레임워크이다.
2021년 8월 19일에 Production 버전인 0.2.0이 릴리즈 되었고, 2022년 11월에 GA버전인 1.0이 출시될 예정이라고 한다.
Feature List는 아래와 같다.

  • OAuth 2.1, OpenID Connect 1.0 Protocol
  • Authorization Code, Client Credential, Refresh Token Grant Type
  • Token Format으로 JWT 사용

Keycloak은 IAM(Identity and Access Management) Open Source로서 2014년 9월에 Production 버전이 릴리즈되었다.
Red Hat SSO의 Upstream 프로젝트로써 사용되며, 무료 라이센스이고 꾸준한 업데이트가 이루어지고 있다.
Feature List는 아래와 같다.

  • 브라우저 애플리케이션 기반 Single Sign-On 및 Signle Sign-Out
  • SAML, OAuth 2.0, OpenID Connect 1.0 Protocol
  • Social Login
  • GUI 기반 Admin Console 제공
  • Theme Custom Support
  • Two-factor Authentication(Google Authenticator, FreeOTP)

OAuth 2.0, OpenID Connect 1.0 Protocol은 두 프로젝트 모두 지원했지만, Keycloak의 경우 자체적인 Browser 기반 Session 관리를 통한 SSO를 지원하기도 하고, 역사가 8년 이상 되다 보니 Document와 Reference 또한 Spring Authorization Server에 비해 풍부했다.
또한 GUI 기반 Admin Console의 제공과 Two-factor Authentication 지원 등 추후 보안을 강화하기 위해 필요한 기능들까지 제공하고, 무엇보다 위 Authorization Server 선정 기준으로 잡은 5가지 항목에 모두 적합하여 Keycloak으로 최종 선정하였다.

2. Keycloak 구축

Keycloak Server Guides에서 여러 환경(OpenJDK, Docker, k8s, ..)에서의 Keycloak을 시작하기 위한 가이드를 제공하여 쉽게 development mode로 시작해 볼 수 있다.

Keycloak을 시작하기 전에, 핵심 용어를 먼저 간단하게 알아보자.

  • Realm: 사용자가 속한 영역, Client 및 User는 Realm별로 구분됨
  • Client: Keycloak을 사용하여 인증/인가를 수행할 애플리케이션 및 서비스
  • ID Token: 사용자에 대한 ID 정보를 제공하는 토큰
  • Access Token: 호출되는 서비스에 대한 액세스 권한을 부여하는 토큰

Keycloak을 설치하고 각 환경에서의 가이드대로 서버를 띄우면, 기본적으로 8080 포트로 서버가 실행된다.
기본으로 제공되는 Master Realm은 Keycloak 관리를 위해 사용되므로, 별도의 Realm을 생성하여 사용해야 한다.
Realm, Client, User 생성 등은 Keycloak getting-started 링크에서 확인할 수 있다.

Keycloak을 Production 에서 띄우기 위해서는 외부 DB 연결, Hostname 설정 등 추가 구성이 필요한데, 관련 내용은 all-config, configuration-production 문서에서 찾을 수 있다.

Istio같은 서비스 메시나 nginx 등을 사용하여 reverse proxy를 구성할 때는,
proxy edge, hostname에 domain name 설정, http-relative-path를 proxy 설정에 맞게 적용해줘야 한다.

Keycloak Admin Console에서 제공되는 대부분의 기능은 Keycloak Admin REST API 에서 Http Endpoint로 별도 제공된다.
이를 호출하려면 Keycloak Token Endpoint에서 Password Grant Type으로 Admin 계정의 Access Token을 발급받아 헤더에 넣어야 한다.
이를 이용해서 Admin Console같은 페이지를 만들 수도 있고, 다른 비지니스 로직과 조합하여 사용할 수 있다.

Java 개발자는 Keycloak Java Adapter를 사용할 수 있다.
Java 코드로 Keycloak Admin REST API를 조작할 수 있고, Admin 계정의 Access Token이 필요하지 않다.
사내에서는 해당 어댑터를 사용하여 Keycloak API와 비즈니스 로직을 조합하여 사용하였다.
샘플 코드는 Github에서 확인할 수 있다.

마냥 장점만 있는 것 같은 Keycloak도 Open Source가 가지는 특유의 단점들이 존재한다.

  1. 필요에 따른 데이터를 추가로 저장하기 위해 Attributes라는 기능을 제공하는데, 이에 대한 암호화는 지원하지 않는다.
    예를 들어, 카드 번호나 지갑 주소 등을 저장해야 하는 경우, Attribute 암호화를 지원하지 않아 문자열을 그대로 DB에 저장해야 하는데, 이는 정보통신망법 등에 위배된다.
    위 예시처럼 관련 법에 따라 암호화가 의무화된 데이터를 저장해야 한다면, 해당 컬럼만 별도의 DB에 암호화하여 저장해야 하는 일이 발생한다.

  2. 기획된 프로세스가 Keycloak에서 지원되지 않는 경우, 문제를 해결하기가 까다롭다.
    예를 들어, 회원가입 프로세스 도중 Email 인증을 해야만 회원가입이 완료되도록 기획이 나왔다면, Keycloak을 사용해서 해결하기는 힘들 것이다.
    Keycloak에서 제공하는 Email 인증 API는 이미 존재하는 회원에 한하여 가능한데, 회원가입 도중 이메일 인증을 선행하려면 회원가입 API -> Email 인증 API -> 이메일 인증 미시행 시 회원 탈퇴 등 여러 API를 하나의 트랜잭션으로 묶어 별도의 서버에서 조합하여 호출하는 방식으로 해결하거나, Keycloak 내부 코드를 변경해야 한다.
    하지만 Keycloak 내부 코드를 변경하는 방법은, 레거시 코드를 변경하는 일이라서 난이도가 높기도 하고, 변경하는 순간 버전 업그레이드가 불가능해지기 때문에 최악의 방법이라고 생각한다.

  3. Keycloak Admin REST API의 테스트 코드 작성이 어렵다.
    회원을 생성하는 Keycloak Admin REST API와 회원의 카드 번호를 암호화하여 별도 DB에 저장하는 로직을 조합하여 제공하는 API가 있다고 가정하자.
    해당 API의 테스트 코드를 작성한다고 했을 때, 호출한 Keycloak API를 롤백시키기가 무척 어렵다.
    Keycloak 내부 코드를 변경하여 테스트를 위한 Api Call이 들어왔을 때는, 모종의 규칙을 정해 보상 트랜잭션이 발생하도록 구성하거나, 혹은 테스트만을 위한 별도의 Keycloak 서버를 두어야 할 것이다.(그마저도 롤백이 가능한 것은 아니라서, 테스트 실행 시 마다 테스트 데이터가 쌓일 것이다.)

3. 프로필 서버 구축

위에 나열한 문제 중 1, 2번 문제를 해결하기 위해, 프로필 서버라는 별도의 서버를 구성하기로 하였다.
Keycloak과 프로필 서버의 관계는 아래와 같다.

  • Keycloak에는 Email, First Name, Last Name과 같은 기본적인 계정 정보만을 저장한다.
  • 프로필 서버에는 회사에서 추가적으로 필요한 데이터들을 저장한다.(이용 동의 내역, image url, ..)
  • Keycloak Admin REST API는 프로필 서버를 반드시 거치도록 Wrapping하여 HTTP API로 제공한다. (Keycloak Admin REST API를 호출하려면 해당 Realm의 Admin 계정 정보가 필요한데, 해당 정보를 노출시키지 않고 서버에서 관리하기 위함)
  • Keycloak Admin REST API로 제공되지 않는 기획들을, 여러 API의 조합(Facade Pettern)과 Keycloak 외부 요소를 활용하여 해결한다.
    필요한 Authorization Server와 추가 정보를 저장할 프로필 서버를 구축하였으니, 다음 포스팅에서는 기존 서비스에 어떤 식으로 SSO를 적용하였는지를 이야기해보겠다.
profile
백엔드 개발자

0개의 댓글