forked from baron/baron-sso
백채널 로그아웃 polling 추가
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
|
||||
핵심은 다음 두 가지입니다.
|
||||
|
||||
1. **Baron SSO가 RP로 보내는 요청 형식은 공통입니다.**
|
||||
2. **RP가 그 요청을 받아 세션을 찾고 지우는 내부 로직은 RP 유형에 따라 달라질 수 있습니다.**
|
||||
1. Baron SSO가 RP로 보내는 요청 형식은 공통입니다.
|
||||
2. RP가 그 요청을 받아 세션을 찾고 지우는 내부 로직은 RP 유형에 따라 달라질 수 있습니다.
|
||||
|
||||
## 결론
|
||||
|
||||
@@ -15,60 +15,64 @@ Baron SSO는 모든 RP에 대해 같은 방식으로 `POST /backchannel-logout`
|
||||
- body: `logout_token=<jwt>`
|
||||
- 검증용 공개키는 `GET /api/v1/auth/backchannel/jwks.json`
|
||||
|
||||
차이는 Baron이 보낸 뒤 **RP 내부에서 세션을 어디서 찾고 어떻게 파기하느냐**입니다.
|
||||
차이는 Baron이 보낸 뒤 RP 내부에서 세션을 어디서 찾고 어떻게 파기하느냐입니다.
|
||||
|
||||
- `PKCE RP`
|
||||
- `server-side-app RP`
|
||||
- `headless login RP`는 `PKCE` 기반 custom login UI 변형
|
||||
|
||||
## Polling 방식에 대한 정리
|
||||
## Polling과 Session Management
|
||||
|
||||
`polling`은 **OIDC Back-Channel Logout 표준 자체에는 없습니다.**
|
||||
`polling`에 가장 가까운 OIDC 개념은 **Back-Channel Logout**이 아니라 **OpenID Connect Session Management**입니다.
|
||||
|
||||
공식 사양은 OP가 RP의 `back-channel logout URI`로 직접 `HTTP POST`를 보내고, 본문에 `logout_token`을 포함하는 방식만 정의합니다. OIDC Back-Channel Logout은 OP와 RP 사이의 direct back-channel communication이며, RP가 주기적으로 OP를 조회해서 로그아웃 여부를 받는 polling 모델은 표준 경로가 아닙니다.
|
||||
공식 사양 근거: [`OpenID Connect Back-Channel Logout 1.0`](https://openid.net/specs/openid-connect-backchannel-1_0.html) [turn3view0].
|
||||
이 방식은 RP 서버가 OP 서버를 주기적으로 polling하는 구조가 아니라, **RP 브라우저 화면 안에서 OP의 `check_session_iframe`과 통신하면서 OP 세션 상태 변화 여부를 확인**하는 구조입니다.
|
||||
|
||||
따라서 polling을 지원하고 싶다면, 그건 `Back-Channel Logout`이 아니라 **커스텀 세션 재검증 또는 heartbeat**로 보는 게 맞습니다.
|
||||
개념적으로는 다음과 같습니다.
|
||||
|
||||
### polling을 쓸 때의 의미
|
||||
```text
|
||||
RP 브라우저 화면
|
||||
↓ 주기적으로 확인
|
||||
OP check_session_iframe
|
||||
↓
|
||||
changed / unchanged / error
|
||||
↓
|
||||
changed면 RP가 재인증 또는 로그아웃 처리
|
||||
```
|
||||
|
||||
Polling을 도입하면 RP는 Baron SSO에 다음과 같은 식으로 주기적으로 확인합니다.
|
||||
즉, 이건 브라우저 기반 front-channel/iframe 방식이지, RP 서버가 OP 서버에 주기적으로 polling하는 Back-Channel Logout 방식은 아닙니다.
|
||||
|
||||
1. 현재 RP 세션이 아직 유효한지 확인합니다.
|
||||
2. Baron 세션이 만료되었거나 연동 해지되었으면 RP 로컬 세션을 지웁니다.
|
||||
3. 유효하면 아무 작업도 하지 않고 다음 주기까지 기다립니다.
|
||||
### Session Management를 쓸 때의 의미
|
||||
|
||||
이 방식은 다음과 같은 상황에서 유용할 수 있습니다.
|
||||
Session Management를 도입하면 RP는 브라우저를 통해 OP 세션 상태 변화를 감지하고, 상태가 바뀌면 로컬 세션을 정리하거나 재인증을 유도합니다.
|
||||
|
||||
- RP가 외부에서 inbound `POST`를 받기 어려운 경우
|
||||
- 백채널 엔드포인트를 노출하기 어렵고, RP가 outbound 요청만 가능할 때
|
||||
- 로그아웃 즉시성보다 단순한 운영을 우선할 때
|
||||
일반적인 흐름은 다음과 같습니다.
|
||||
|
||||
하지만 이 방식의 한계도 분명합니다.
|
||||
1. 로그인 시 RP가 OP 세션 식별에 필요한 정보를 보관합니다.
|
||||
2. RP 화면이 `check_session_iframe` 상태를 주기적으로 확인합니다.
|
||||
3. OP 세션이 바뀌면 `changed`를 받습니다.
|
||||
4. RP가 로컬 세션을 삭제하거나 재인증을 시작합니다.
|
||||
|
||||
- 로그아웃이 실시간이 아니라 주기 지연을 가집니다.
|
||||
- 요청량이 늘어납니다.
|
||||
- RP가 자체적으로 polling 스케줄과 실패 복구를 관리해야 합니다.
|
||||
|
||||
### polling 기반 로직 구성 예시
|
||||
|
||||
polling을 선택한다면 보통 아래 구조로 갑니다.
|
||||
### Session Management 기반 로직 구성 예시
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant RP as RP
|
||||
participant Baron as Baron SSO
|
||||
participant Browser as RP Browser
|
||||
participant RP as RP App
|
||||
participant IFrame as OP check_session_iframe
|
||||
participant Store as RP Session Store
|
||||
|
||||
loop 주기적 확인
|
||||
RP->>Baron: 세션 유효성 조회 요청
|
||||
Baron-->>RP: 유효 / 무효 응답
|
||||
alt 유효
|
||||
RP->>RP: 로컬 세션 유지
|
||||
else 무효
|
||||
Browser->>IFrame: session state check
|
||||
IFrame-->>Browser: changed / unchanged / error
|
||||
alt unchanged
|
||||
Browser->>RP: 로컬 세션 유지
|
||||
else changed
|
||||
Browser->>RP: 재인증 또는 로그아웃 유도
|
||||
RP->>Store: session destroy
|
||||
RP->>RP: 세션 매핑 제거
|
||||
else error
|
||||
Browser->>RP: 재시도 또는 안전 로그아웃
|
||||
end
|
||||
end
|
||||
```
|
||||
@@ -76,11 +80,11 @@ sequenceDiagram
|
||||
권장 구성은 다음과 같습니다.
|
||||
|
||||
1. 로그인 시 `sid` 또는 `sub`를 RP 세션에 저장합니다.
|
||||
2. 주기 작업이 Baron의 세션 유효성 또는 사용자 프로필 확인 API를 호출합니다.
|
||||
3. Baron 세션이 무효면 RP가 로컬 세션을 삭제합니다.
|
||||
4. 민감한 화면 진입 전에도 한 번 더 재검증할 수 있습니다.
|
||||
2. RP 화면이 `check_session_iframe` 상태를 주기적으로 확인합니다.
|
||||
3. `changed`가 오면 RP가 로컬 세션을 삭제하거나 재인증을 시작합니다.
|
||||
4. `error`가 반복되면 안전하게 로그아웃 처리하는 정책을 둘 수 있습니다.
|
||||
|
||||
이 방식은 `backchannel logout`과는 별개로 설계하는 것이 좋습니다.
|
||||
이 방식은 `Back-Channel Logout`과 별개로 설계하는 것이 좋습니다.
|
||||
|
||||
## 공통 시퀀스
|
||||
|
||||
@@ -174,7 +178,7 @@ server-side-app RP는 confidential client이므로, 서버 세션 구조와 백
|
||||
|
||||
### headless login RP
|
||||
|
||||
headless login은 **별도의 로그아웃 타입이 아니라 PKCE 계열의 로그인 변형**입니다.
|
||||
headless login은 별도의 로그아웃 타입이 아니라 PKCE 계열의 로그인 변형입니다.
|
||||
|
||||
즉, 로그인 시에는 custom login UI가 있고 RP backend가 headless login API를 호출하지만, 백채널 로그아웃은 결국 동일한 패턴으로 처리합니다.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user