inerit와 블로그를 같은 Keycloak에 연결하면 자연스럽게 로그인도 이어질 거라고 생각하기 쉽다. 하지만 인증 서버를 공유한다는 사실과 각 서비스가 로그인 상태를 만드는 것은 다른 문제였다.

2026년 11월 작업 당시 한쪽에서 로그인해도 다른 쪽에서는 인증이 이어지지 않았고, 재인증이 필요했다. 이후 양방향 로그인 연계와 서비스별 권한, 명시적 로그아웃 후 즉시 재로그인 방지, 기존 계정 이전을 다뤘다. 이 글은 당시 작업 기록에서 얻은 설계상의 교훈이다. 현재 운영 상태를 다시 검증한 결과는 아니다.

중앙 인증과 서비스 세션은 다르다

사용자가 인증 서버에 로그인되어 있어도, 새로 방문한 서비스는 아직 그 결과를 확인하지 않았을 수 있다. 서비스가 인증 상태를 확인하고 필요한 검증을 거쳐 자체 로그인 상태를 만들어야 한다. 다른 서비스의 쿠키를 그대로 읽어 오는 것과는 다르다.

장애를 살필 때도 질문을 분리해야 한다.

  • 인증 서버에 유효한 SSO 세션이 있는가?
  • 새 서비스가 인증 확인을 시작했는가?
  • 응답 검증과 기존 계정 연결이 성공했는가?
  • 서비스에서 허용할 사용자와 권한이 맞는가?

Keycloak은 SSO 사용자 세션과 클라이언트 세션을 구분하고, 애플리케이션 자체 세션도 별도로 존재할 수 있다. 만료 정책을 한 덩어리로 보면 어느 경계에서 상태가 끊겼는지 파악하기 어렵다. Keycloak 세션 만료 설정

자동 로그인과 강제 로그인은 다르다

공개 페이지를 열었을 때마다 인증 화면으로 보내는 것과, 기존 인증이 있는 경우에만 로그인 상태를 이어 주는 것은 다른 정책이다.

예를 들어 Keycloak JavaScript 어댑터의 login-required와 check-sso는 각각 다른 진입 경험을 제공한다. 이는 차이를 설명하는 예시일 뿐, 당시 inerit에서 해당 옵션을 사용했다는 뜻은 아니다. OpenID Connect의 prompt=none도 상호작용 없이 처리하도록 요청할 뿐, 인증이나 동의를 생략해 주지는 않는다. 필요하면 login_required 같은 결과가 돌아온다. 이를 무조건 재시도하면 인증 서버와 서비스 사이를 반복해서 오갈 수 있다. Keycloak JavaScript 어댑터, OpenID Connect 인증 요청

iframe 기반의 조용한 인증 확인은 브라우저의 서드파티 쿠키 제한에도 영향을 받는다. 한 브라우저에서 성공한 것만으로 모든 환경에서 같은 동작을 보장할 수는 없다.

인증과 이용 승인은 별개다

중앙 인증은 사용자가 누구인지 확인하지만, 특정 서비스의 이용을 허용할지까지 자동으로 결정하지 않는다. 한 서비스에서 승인된 계정이라도 다른 서비스의 이용 조건은 다를 수 있다. 이 경우 비밀번호를 다시 묻기보다 승인 대기나 접근 제한 상태를 구분해 알려주는 편이 낫다.

권한은 Keycloak의 클라이언트 역할로 표현하거나 서비스 자체에서 관리할 수 있다. 어느 쪽을 택하든 화면 표시뿐 아니라 보호된 요청을 처리하는 곳에서도 검증해야 한다. 프로토콜의 사용자 동의와 서비스 운영상 이용 승인은 서로 다른 개념이다. Keycloak 클라이언트 역할

로그아웃은 사용자의 의도까지 포함한다

서비스 세션을 지웠더라도 중앙 SSO 세션은 남아 있을 수 있다. 이때 페이지가 즉시 자동 로그인을 다시 시작하면 사용자는 로그아웃 버튼을 눌렀는데 곧바로 로그인된 화면을 본다.

먼저 현재 서비스만 로그아웃하는지, 중앙 세션까지 종료하는지 정해야 한다. 서비스 단위 로그아웃이라면 자동 로그인 억제 상태를 언제까지 유지하고 명시적인 로그인 요청에서 어떻게 해제할지도 결정해야 한다. 이 상태는 사용자 경험을 위한 것이며 서버의 인증·인가 검사를 대체하지 않는다.

중앙 로그아웃 역시 다른 서비스의 세션과 화면이 즉시 정리된다고 가정해서는 안 된다. OpenID Connect에는 인증 서버에 종료를 요청하는 RP-Initiated Logout과 서버 간 통지를 다루는 Back-Channel Logout이 별도로 정의되어 있다. 실제 적용 방식은 서비스의 요구와 구현에 따라 확인해야 한다.

계정 이전과 검증

기존 계정 이전에서는 단순히 로그인이 되는지만 볼 수 없다. 데이터 소유권과 서비스별 승인 상태가 올바른 계정에 연결되는지, 불명확하거나 중복된 계정은 없는지 확인해야 한다. OpenID Connect에서 식별자의 안정성을 다루는 기준은 iss와 sub의 조합이다. 다만 이 식별자가 있다고 해서 기존 로컬 계정과의 연결이 자동으로 증명되는 것은 아니다. OpenID Connect 식별자

검증할 때는 로그인 성공 한 번보다 상태 전환을 따라가는 게 중요하다.

  1. 어느 서비스에서 시작해도 다른 서비스로 이동할 때 의도한 인증 흐름이 동작하는가?
  2. 미인증 사용자가 공개 화면에서 로그인 반복에 빠지지 않는가?
  3. 인증됐지만 이용 승인이 없는 경우 적절한 안내가 나오는가?
  4. 명시적 로그아웃 후 새로고침과 재방문에서도 의도한 정책이 유지되는가?
  5. 중앙 세션과 서비스 세션의 만료 시점이 달라도 복구할 수 있는가?
  6. 기존 계정의 데이터와 권한이 올바르게 유지되는가?

SSO의 핵심은 로그인 화면을 한 번 줄이는 데서 끝나지 않는다. 인증 서버가 증명한 신원과 각 서비스의 세션, 권한, 사용자의 로그아웃 의도를 각각 어디에서 관리할지 결정해야 한다.