티스토리 뷰

개요

  • 마이크로서비스 시대에서 요청자에 대한 인증(Authentication)과 인가(Authorization)는 더욱 더 중요한 개념으로 자리매김하고 있다. 대부분의 개발자가 주요 기능을 먼저 설계하고 인증과 인가를 가장 늦게 설계해본 경험이 있을 것이다. 꽤나 귀찮고 반복적이면서 실수가 용납되지 않는 것이 인증과 인가라고 말할 수 있다. 만약, 국제적인 인증, 인가 표준(OIDC, SAML, OAuth 2.0 등)을 모두 제공하는 서비스가 완성품으로 무료로 제공한다면? 쓰지 않을 이유가 없을 것이다. 이번 글에서 설명할 JBoss Keycloak이 바로 이러한 인증, 인가를 대행해주는 오픈 소스 솔루션이다.

국내 중요정보 보관에 대한 법적 근거

  • 인증, 인가를 본격적으로 다루기에 앞서 중요정보에 대한 국내에서의 법적 근거를 확인해볼 필요가 있다. 그간 금융권에서는 정부가 2016년 전자금융감독규정을 개정, 클라우드 서비스 이용 가이드를 마련하여 개인신용정보고유식별정보를 제외한 비중요정보에 한정하여 클라우드 사용을 허용한 바 있다. 이로 인해 중요정보를 다루는 핀테크 업계의 스타트업 입장에서 국내 IDC에 자체 물리 서버를 구축하고 관리해야 하는 부담을 주었다.
  • 2018-07-15 금융위원회금융권 클라우드 이용 확대 방안을 발표했다. 이에 따르면 2019년 1월부터 금융사 및 핀테크 기업은 고객의 개인신용정보고유식별정보의 저장소로 그동안 법으로 금지되었던 클라우드를 이용할 수 있게 된다. 즉, 네이버 클라우드 플랫폼과 같은 국내 기업의 클라우드부터 AWS와 같은 국외 기업의 국내 리전까지 중요정보를 저장할 수 있게 되는 것이다. AWS의 경우 2016-01-07부터 서울 리전을 제공하고 있으며 2017-12-27 부로 한국인터넷진흥원이 발급하는 ISMS 인증을 획득한 상태이다. [관련 링크1] [관련 링크2]
  • 한편, 개인정보보호법 제23조와 행정자치부한국인터넷진행원이 2017-01 발간한 개인정보의 암호화 조치 안내서에 따르면 저장소에 중요정보 저장시 암호화할 것을 법으로 강제하고 있다. 이에 따르면 비밀번호, 바이오 정보, 주민등록번호, 신용카드번호, 계좌번호, 여권번호, 운전면허번호, 외국인등록번호가 암호화 대상으로 언급되어 있어 인증, 인가 서비스 설계시 고려해야 한다. [관련 링크]

JBoss Keycloak 아키텍쳐

  • JBoss Keycloak은 하나의 완성품으로 작동하는 웹 애플리케이션이다. 내부적으로는 JBoss Undertow 기반 위에 JBoss RESTEasy(JAX-RS 2.1 구현체)로 서비스되며 노드 간의 세션 클러스터링과 캐시를 위해 JBoss Infinispan을 사용한다.

JBoss Keycloak 설치

  • CentOS 7 환경에서 JBoss Keycloak의 설치는 아래와 같이 진행한다.
### 운영체제에 keycloak 사용자를 생성하고 비밀번호 설정
$ useradd keycloak
$ passwd keycloak

### /opt 디렉토리에 JBoss Keycloak를 설치하고 keycloak 사용자에게 소유권 이전
$ cd /opt
$ wget https://downloads.jboss.org/keycloak/4.5.0.Final/keycloak-4.5.0.Final.zip
$ unzip keycloak-4.5.0.Final.zip
$ rm -f keycloak-4.5.0.Final.zip
$ mv keycloak-4.5.0.Final keycloak
$ chown -R keycloak:keycloak keycloak

JBoss Keycloak의 실행

  • JBoss Keycloak의 실행 방법은 아래와 같다.
### keycloak 사용자로 로그인
$ su - keycloak
$ cd /opt/keycloak/bin

### 일반적인 JBooss Keycloak의 실행, 루프백 인터페이스로부터만 접속이 가능
$ ./standalone.sh

### 보안이 완화된 JBooss Keycloak의 실행, 외부 인터페이스로부터의 접속도 가능
$ ./standalone.sh -b 0.0.0.0

### 리스닝 포트를 기본값인 8080에 100을 더한 8180으로 실행
$ ./standalone.sh -b 0.0.0.0 -Djboss.socket.binding.port-offset=100
  • 한편, Keycloak은 보안을 위해 localhost(또는 127.0.0.1) 루프백 인터페이스로부터의 요청만을 허가한다. 따라서 외부 인터페이스로부터의 요청을 허가하려면 Keycloak 실행시 -b 0.0.0. 옵션을 추가해야 한다.

관리자 계정 생성

  • Keycloak을 설치한 후 가장 먼저 해야할 일은 관리자 계정을 생성하는 것이다. 아래와 같이 스크립트를 실행하여 생성한다. 관리자 계정 생성 후 실행 중인 Keycloak를 종료하고 다시 실행(또는 서비스 재시작)해야 한다.
### admin 이라는 어드민 계정을 생성
$ ./add-user-keycloak.sh -u admin
Password: *****
Added 'admin' to '/opt/keycloak/standalone/configuration/keycloak-add-user.json', restart server to load user

### Keycloak 애플리케이션 실행
$ ./standalone.sh -b 0.0.0.0

Admin Console 접속

  • 이제 Keycloak의 어드민 콘솔에 접속해볼 차례이다. 웹 브라우저를 실행하고 http://localhost:8080/auth에 접속한다. (/auth 문자열을 생략해도 자동으로 리다이렉트된다.) 접속 후 Administration Console을 클릭하면 로그인 페이지가 등장한다. 앞서 생성한 어드민 계정으로 로그인하면 어드민 콘솔에 접속할 수 있다.

인증, 인가 관련 용어

  • OIDC(Open ID Connect): OAuth 2.0이 인가만 다루는 스펙이라면 OIDCOAuth 2.0을 포함하여 인증과 인가를 모두 포괄하는 스펙이다. 한 사이트에서 로그인하면 다른 사이트에서도 로그인이 되는 SSO(Single Sign-On) 기능 구현을 위한 대표적인 수단으로 사용된다. JBoss Keycloak의 경우 클라이언트를 위한 OpenID 서버로서 기능할 수 있다. 웹사이트의 사용자는 JBoss Keycloak에 접속하여 로그인을 수행하며 이에 대한 결과로 ID Token(로그인 사용자의 정보)과 Access Token(권한 위임에 대한 정보)이 JWT의 형태로 발급되어 SSO를 가능하게 한다. [관련 링크1] [관련 링크2]

JBoss Keycloak 관련 용어

  • 본격적으로 JBoss Keycloak을 구성하기 전에 관련 용어에 대해서 간단히 숙지할 필요가 있다. 필수적으로 이해가 필요한 주요 용어는 아래와 같다.
  • Realm: 인증, 인가가 작동하는 범위를 나타내는 단위이다. SSO(Single Sign-On)를 예로 들면 특정 클라이언트들이 SSO를 공유한다면 그 범위는 그 클라이언트들이 공통적으로 속한 Realm에 한정된다. 기본적으로 삭제가 불가능한 Master라는 Realm이 제공된다.
  • Client: JBoss Keycloack에게 인증, 인가 행위를 대행하도록 맡길 애플리케이션을 나타내는 단위이다. 웹사이트일수도 있고, REST API를 제공하는 서비스일수도 있다. 하나의 Realm은 자신에게 종속된 n개의 Client를 생성하고 관리할 수 있다.
  • User: 실제 각 Client에 로그인할 사용자를 나타내는 단위이다. 하나의 Realm은 자신에게 종속된 n개의 User를 생성하고 관리할 수 있다. 기본적으로 User 개체는 Username, Email, First Name, Last Name 4개 항목을 가질 수 있는데 Custom User Attributes 기능을 통해 커스텀 항목을 자유롭게 추가할 수 있다. (다만, 추가된 항목이 사용자 등록 및 관리 화면에 출력되려면 커스텀 테마 등록 및 수정이 필요하다.)

Client 애플리케이션 개발

  • 이제 JBoss Keycloak에게 인증, 인가 행위를 위탁할 Client 애플리케이션을 개발해볼 차례이다. https://start.spring.io에 방문하여 새로운 프로젝트를 생성하도록 한다. 유의할 점은 Dependencies 항목에 Web, Keycloak을 추가하도록 한다. 나머지 설정은 입맛에 맞게 자유롭게 해도 무방하다.
  • 생성한 프로젝트 내의 /src/main/resources/application.properties 파일의 이름을 application.yml으로 변경하고 아래 내용을 추가한다. 사실상 아래 설정 만으로 JBoss Keycloak을 사용할 준비는 끝난다.
server:
  port: 8081

keycloak:
  auth-server-url: http://127.0.0.1:8080/auth
  realm: test
  resource: test
  public-client: true
  principal-attribute: test
  securityConstraints[0]:
    authRoles[0]: admin
    securityCollections[0]:
      patterns[0]: /test/*
  • server.port 항목은 Client 웹 애플리케이션 시작시 리스닝할 포트 번호를 의미한다. 같은 로컬 내의 8080 포트를 이미 앞서 실행한 JBoss Keycloak 애플리케이션이 사용하기 때문에 충돌을 피해 8081 포트로 설정했다. 운영 환경에서는 서로 다른 물리 서버에서 기동되므로 이 설정은 큰 의미가 없다.
  • keycloack 항목은 인증, 인가를 위한 모든 정보를 담고 있다. auth-server-url에는 기동 중인 JBooss Keycloak의 서비스 주소를 입력한다.
  • realm 항목에는 인증, 인가를 공유하는 Realm을 입력한다. 본인이 생성한 값을 입력한다.
  • resource 항목에는 본 애플리케이션에 해당하는 Clientfmf 입력한다. 본인이 생성한 값을 입력한다.
  • patterns[] 항목에는 인증, 인가가 요구되는 본 애플리케이션의 리소스 경로를 입력한다. 위 예제의 경우 /test/로 시작하는 모든 요청 리소스 경로에는 admin 권한을 가진 사용자 계정의 로그인을 요구하도록 설정했다.
  • 이제 로그인이 요구될 리소스의 경로를 작성할 차례이다. /src/main/java/TestController.java 파일을 새로 작성한다. 위 설정대로 /test 요청시 로그인을 요구하도록 의도하기 위한 목적으로 비즈니스로 로직 상으로는 큰 의미는 없다.
@Controller
public class TestController {

    @GetMapping(path = "/test")
    public String test(Model model) {

        return "test";
    }
}
  • Client 역할을 수행할 본 애플리케이션의 개발이 완료되었다. 애플리케이션을 기동하고 웹 브라우저에서 http://localhost:8081/test를 입력하면 JBoss Keycloack의 로그인 화면으로 리다이렉트되는 것을 확인할 수 있을 것이다.

커스텀 테마

  • JBoss Keycloak은 기본 테마로 base, keycloak(기본 테마) 2개를 제공한다. 아마 웹사이트를 제작하면서 기본 테마를 그대로 사용할 일은 없을 것이다. 대부분 각 환경에 알맞는 커스텀 테마를 제작하게 된다. JBoss KeycloakFreeMarker 템플릿 엔진 기반의 커스텀 테마를 지원한다. 기존 테마와 동일한 구조의 커스텀 테마를 제작한 후 /opt/keycloak/themes 디렉토리에 업로드하면 된다. 커스텀 테마를 제작하면서 앞서 언급한 User에 대한 커스텀 애트리뷰트도 노출시킬 수 있다.

참고 글

댓글
댓글쓰기 폼