Keycloak 에서 OAuth2.0 접근 토큰에 제한을 두는 방법은 다음과 같이 있다.
1. 토큰 접근을 제한하기 위한 audience 사용
2. 역할을 사용해 토큰 액세스 제한
3. 토큰 접근을 제한하기 위한 범위 활용
위 3가지 방법은 상황에 맞춰 사용하면 된다.
예를 들어,
신뢰하지 못하는 서비스에 토큰 요청을 막고 싶다면 1번을,
어플리케이션에서 특정 역할이 담겨져 있는지 확인하고 없다면 403(Forbidden) 을 응답하도록 미들웨어를 추가한다면 2번을,
리소스에 대한 접근 권한을 사용자 대신 동의하는 서드파티 어플리케이션의 경우 3번을 사용하면 된다.
이번 포스트에서는 3번을 활용해서 어떻게 리소스 권한을 세밀하게 제어하는지 살펴볼 것이다
위 소스코드를 다운 받아 실행시키면 플레이 그라운드 어플리케이션이 띄워진 것을 볼 수 있다.
플레이 그라운드 어플리케이션에 사진 앨범을 보여주고 관리하는 기능이 있다고 가정하자. 앨범 보기, 앨범 생성, 앨범 삭제에 접근할 수 있는 사진 앨범 서비스가 제공된다. 그리고 플레이 그라운드 어플리케이션에서는 앨범 보기 권한이 기본적으로 필요하고, 생성 및 제거는 옵션으로 지정되어 있다.
사용자가 플레이 그라운드에 회원가입(로그인)을 하고 앨범을 생성한다 상상해보자. 사용자는 회원가입(로그인)할 때 인가 서버로부터 "플레이 그라운드가 당신의 앨범 목록을 볼 수 있도록 권한을 허가하시겠습니다?" 라는 문구를 볼 것이다. 사용자가 OK 한다면 플레이 그라운드는 사용자의 앨범 목록을 이쁘게 출력해주는 페이지를 제공할 것이다. 그리고 사용자가 특정 앨범을 생성하려고 시도한다. 그럼 인가 서버로부터 "플레이 그라운드가 당신의 앨범 목록에 앨범을 추가할 수 있도록 권한을 허가하시겠습니다?" 라는 동의페이지를 보여줄 것이다.
정리하면,
- 앨범 목록 보기 권한 => 사용자가 회원가입(로그인)하면 기본적으로 받아야할 권한
- 앨범 생성 권한 => 어플리케이션이 추가로 받아야할 권한
- 앨범 삭제 권한 => 어플리케이션이 추가로 받아야할 권한
이를 Keycloak 을 통해 구현해보자.
앨범 보기, 앨범 생성, 앨범 삭제에 대한 클라이언트 스코프를 각각 생성한다.
이후 oauth-playground 클라이언트에 위 3개의 클라이언트 스코프를 추가해주고 Assigned Type 을 다음과 같이 설정한다
albums: view => default
albums: create => optional
albums: delete => optional
2-Authentication 에서 scope
에 아무런 값을 입력하지 않고 Send Authentication Request
버튼을 누르면 동의화면 다음으로 Response 에 albums:_view
가 있는 걸 볼 수 있다.
이제 플레이 그라운드가 사용자 앨범 목록에 새로운 앨범을 추가한다고 해보자. 그럼 scope 에 albums:create
를 넣어주고 다시 Send Authentication Request
버튼을 누르면 동의화면 다음으로 Response 에 albums:_create
가 있는 걸 볼 수 있다.
Keycloak 에서 제공하는 토큰 검사 엔드포인트를 호출하거나 토큰을 직업 확인하는 두가지 방법으로 토큰을 검증할 수 있다.
단순히 Keycloak 토큰 검증 엔드포인트를 호출하여 검증하는 방법이기 때문에 가장 간단한 방법이다. 그리고 어플리케이션 입장에서도 단순 호출만하면 되기 때문에 Keycloak 에 덜 의존한다. 그러나 토큰 검사 엔드포인트를 사용할 때마다 Keycloak 서버(인가 서버)에 부하가 가는 단점이 있다. 이를 극복하기 위해 어플리케이션 단에서 캐시를 하거나 이미 검증된 토큰은 몇 분 동안 재검증하지 않도록 설정한다.
Keycloak 토큰 검증 엔드포인트를 호출하지 않고 직접 어플리케이션에서 검증하는 방법이다.
접근 토큰이 JWT 라면 header, payload, signature 세 개로 나눌 수 있다. 이때 해당 토큰이 유효한 토큰인지 signature 를 통해 검증할 수 있다.
어플리케이션은 Keycloak 으로부터 받은 공개키를 스토리지에 저장한다. 그리고 요청올 때마다 포함된 접근 토큰을 이전에 받은 공개키를 사용해 해당 토큰이 Keycloak 으로부터 왔는지 검증한다. 서명 검증이 끝나면 접근 토큰이 만료되었는지, 발급자 및 audience, 클레임 등을 검증한다.