KeyCIoak - 모던 애플리케이션을 위한 ID 및 접근관리 | 에이콘출판(주) | 스티안 토르거센, 페드로 이고르 실바 지음, 최만균 옮김
서적을 참고하여 요약한 시리즈 글이다.
1. 세션 관리
세션은 클라이언트의 인증 여부, 인증 기간, 재인증 시기 등을 결정한다. 따라서 세션을 활용하면 동일한 영역 내의 서로 다른 클라이언트를 인증하는 Single Sign On을 제공할 수 있다.
세션은 토큰이 유효한 토큰인지 확인하기 위한 보안 계층을 제공하는 역할도 한다. 그리고 메모리에 저장되어 Keycloak의 전반적인 성능에 직접적인 영향을 미친다.
1.1 세션 생명주기 관리
1.1.1 세션 생명주기
Keycloak은 주기적으로 만료된 세션을 확인한다. 기본적으로 15분이며 이 값도 조절이 가능하다.
Keycloak은 다양한 레벨에서 세션을 생성한다. 첫 번째 레벨은 사용자 세션으로 SSO(Single Sign On) 세션이라고도 한다. 이는 사용자의 활동을 추적하기 위함이다. 두 번째 레벨은 클라이언트 세션이다. 각 클라이언트의 활동을 추적하기 위함이며, 토큰의 유효성 및 애플리케이션에서 토큰을 사용하는 방식과 밀접하게 관련돼 있다.
여기서 다룰 생명주기는 SSO 세션의 생명주기다. 해당 세션이 활성 상태로 유지되는 최대시간과 만료되는 시간을 설정할 수 있다. SSO 세
션이 만료되면 관련된 모든 클라이언트 세션도 만료된다.
1.1.2 세션 설정
세션 생명 주기를 설정하기 위해서 Realm Settings - Sessions 탭에 접근한다.(책에서는 Tokens에 접근하라는데, 버전업되면서 탭이 분리 된것 같음)
여기서 Session Max는 세션의 최대 생명주기 기간이며 10시간을 의미한다. 하지만 Session Idle이 30분으로 설정되어있다. 이는 30분 이내에 사용자의 활동을 확인하지 못하면 최대 시간과 상관없이 세션을 만료시킨다는 의미이다.
클라이언트 세션 설정값
SSO 세션이 만료되지 않은 상태인데 클라이언트 세션만 만료된 상태이면 사용자가 재인증을 반드시 수행할 필요는 없지만 클라이언트는 신규 토큰을 생성하기 위해서 재인증을 수행해야한다. 클라이언트 재인증을 위해 사용자는 Keycloak으로 리다이렉트되고 브라우저를 사용하고 있다면 사용자 경험에 영향을 미칠 수 있다.
세션 주기가 짧을수록 보안성은 뛰어나지지만 사용자의 경험에는 부정적인 영향이 갈 수 있다. 그럼에도 불구하고 보안을 위해 짧은 세션주기를 설정하는 것을 권장한다.
1.2 활성 세션 관리
Sessions 탭에서 현재 활성화되어 있는 세션들을 확인할 수 있다.
그리고 유저별로 세션 확인을 위해서는 users -> detail -> sessions 탭에 들어가면 된다.
일반적인 경우에는 단일 세션을 가진 사용자와 여러 클라이언트가 표시된다. 이는 사용자가 브라우저를 사용해 인증하는 일반적인 SSO 시나리오에 적합하다. 그리고 이 경우 동일 세션이 서로 다른 클라이언트를 인증하기 위해 재사용된다. 만약 사용자가 브라우저를 닫거나 쿠키를 지우거나 다른 기기를 사용하여 인증하면 추가적인 사용자 세션이 생성될 수 있다.
1.3 사용자 세션 조기 종료
realm에서 세션을 확인하는 경우 Action - Sign out all active sessions로 해당 realm에 활성화된 세션들을 모두 만료시킬 수 있다.
사용자 레벨에서도 log out all sessions 버튼으로 세션 종료가 가능하다.
Admin URL을 통해 Keycloak에서 발생한 세션 만료를 애플리케이션에 알림으로 전달하는 방법도 있다고 한다. 다만 이 방식은 Keycloak 어댑터를 사용하는 애플리케이션에서만 사용할 수 있다고 한다. 필요하면 따로 공식문서를 통해 공부하도록 한다.
1.4 쿠키 개념 및 세션과의 관련성 이해
HTTP는 무상태 프로토콜이며 브라우저와 서버 사이의 상태를 공유하기 위해서 쿠키를 사용한다. Keycloak은 사용자가 브라우저를 통해 통신하는 경우 사용자의 세션을 추적하기 위해서 HTTP 쿠키를 활용한다. Keycloak은 KEYCLOAK_IDENTITY 쿠키를 통해 브라우저 세션을 서버의 사용자 세션과 연동한다. KEYCLAOK_IDENTITY 쿠키가 유출되거나 탈취된 경우 사용자 세션의 보안이 위협을 받을 수 있다.
KEYCLOAK_IDENTITY 쿠키는 XSS 및 하이재킹 공격을 방지하기 위해서 HttpOnly 쿠키로 설정된다. 해당 쿠키의 만료는 사용자 세션에 설정된 최대 시간 값을 기반으로 한다. 만약 realm의 remember me 설정을 활성화하고 사용자가 이 옵션을 활성화하는 경우 쿠키의 만료 기간은 사용자 세션에 설정된 최대 시간은 고려되지 않고 1년으로 설정된다.
보안을 위해 HTTPS를 사용하는 채널을 통해서만 Keycloak에 접근할 수 있도록 하는 것이 중요하다. HTTPS를 사용하는 경우 secure 속성은 쿠키가 평문으로 전송되지 않도록 하고, SameSite=none 속성은 보안 연결을 사용하는 사이트 간 요청에서만 쿠키가 전송되도록 해준다.
2. 토큰 관리
토큰의 유효성은 세션에 따라 달라진다. 토큰은 각각 생명주기를 가지며 토큰이 유효한 것으로 간주되는 기간은 토큰이 인증된 방식에 따라 달라진다. JWT를 토큰 형식으로 사용하는 경우, Keycloak은 애플리케이션이 서버에 대한 추가적인 통신없이 로컬에서 토큰을 검증하고 검사할 수 있도록 지원한다. 하지만 JWT 토큰을 사용하는 경우 토큰이 유효한 생명 주기를 갖고 있더라도 세션이 만료되면 토큰이 무효화된다.
앞서 배웠듯이 토큰은 다음 3가지가 존재한다.
- ID 토큰
- Access 토큰
- Refresh 토큰
ID 토큰과 Access 토큰은 동일한 생명주기를 가진다. 두 토큰 모두 수명이 짧고 토큰 스토리지가 가장 안전하지 않은 공용 클라이언트에서 일반적으로 사용된다. Access 토큰은 유출될 가능성이 있으므로 수명주기와 유효성 관리가 보안에 영향을 주는 핵심 요소가 된다.
Refresh 토큰은 상대적으로 수명이 길기 때문에 공격자에게 타깃이 된다. 따라서 만료와 폐기를 위한 명확한 전략이 필요하다.
2.1 ID 토큰 및 Access 토큰 생명주기 관리
2.1.1 Access Token Lifespan
토큰의 관리는 Realm Settings - Tokens 탭에서 가능하다. Access Token의 Lifespan은 기본 1분으로 지정되어 있다. 책에서 소개하는 기본값은 5분인데, 버전업이 되면서 업데이트 된 것 같다. 보안을 위해 성능 손해를 감수하더라도 더 짧게 지정한 것 같다. 이 값이 ID 토큰의 유효기간과도 일치한다.
2.2 Refresh 토큰 생명주기 관리
2.2.1 Refresh 토큰 사용
Refresh 토큰의 생명주기는 클라이언트 세션에 설정된 시간을 기반으로 계산된다. realm 수준의 Client Session Max를 설정하거나 이 값이 지정되지 않은 경우 SSO Session Max 설정에서 사용자 세션으로 설정한 값으로 사용된다.
Refresh 토큰과 관련하여 유념하고 있어야할 사항들은 다음과 같다.
- Refresh 토큰은 인증 코드와 같은 특정 권한 부여를 사용해 Keycloak에서 사용자를 인증한 후 항상 클라이언트 세션과 연동된다.
- 연동된 사용자 및 클라이언트 세션이 만료되지 않은 경우 유효한 것으로 간주된다.
- 클라이언트는 클라이언트 세션이 활성화된 경우에만 refresh 토큰을 사용하여 신규 토큰을 획득할 수 있다.
2.2.2 Refresh 토큰 로테이션 활성화
로테이션은 합법적인 클라이언트가 refresh 토큰을 요청하는 경우 기존 refresh 토큰을 무효화하여 refresh 토큰이 유출된 경우 영향을 줄이기 위한 전략이다. 로테이션 기능을 활성화하면 신규 및 유효한 refresh 토큰을 갱신하기 위해서 공격자와 합법적인 클라이언트 모두를 재인증한다.
Realm settings - Tokens 탭 - Revoke Refresh Tokens의 토글을 활성화하여 로테이션 기능을 켤 수 있다. 토글을 ON 하면 Refresh Token Max Reuse 항목이 추가로 나온다. 기본값은 0이며 이런 경우 refresh 토큰은 한 번만 사용이 가능하다.
공용 클라이언트의 경우 토큰 엔드포인트에 인증하기 위해서 자격증명을 제공할 필요가 없으므로 안전하지 않다. 이를 막기 위해 발신자 제한 토큰(sender-constrained token) 사용을 해야하고 이를 위해 상호(Mutual) TLS 클라이언트 인증 사용을 고려해야한다.
2.2.3 토큰 폐기
앞서 살펴본 내용대로 세션이 만료되면 토큰은 더 이상 유효하지 않은 것으로 간주된다.
사용자와 클라이언트에 관계없이 세션들을 만료하는 방법은 Sessions - Action - Revocation을 통해 날짜를 지정하는 것이다.
Not Before로 값을 주어 특정 시점으로 지정할 수 있다. 지정된 시간 전에 토큰이 생성되는 경우 토큰 유효성 검사에 실패하도록 realm 설정을 업데이트하는 것이다. 클라이언트에게 이런 사항을 전달하는 기능이 Push 버튼인데, 이것은 Keycloak 어댑터를 사용하는 애플리케이션에서만 가능하다. Keycloak으로부터 이런 이벤트를 수신하기 위해 Admin URL을 사용해야한다. 아래 문서에서 확인 가능하다.
https://www.keycloak.org/docs/latest/server_admin/#oidc-clients
특정 엔드포인트를 지정하여 RFC 7009 기반의 토큰 폐기도 할 수 있다. _oidc_endpoints 를 참고하여 엔드포인트를 지정하면 된다.
'Programming-[Backend] > Keycloak' 카테고리의 다른 글
Authorization flows with Keycloak(CIBA, PKCE, Auth-code, SA) (0) | 2024.09.08 |
---|---|
Keycloak - 12. Keycloak 확장 (0) | 2024.08.10 |
Keycloak - 10. 사용자 인증: OTP, WebAuthn, passkey (0) | 2024.08.09 |
Keycloak - 9. 사용자 관리, LDAP 통합, Social Login (0) | 2024.08.07 |
Keycloak - 8. 리버스 프록시 설정, 테스트 (0) | 2024.08.05 |