두 앱 SSO와 API 권한 실습
결론부터
SSO는 Keycloak session을 재사용하고, API 허용은 새 access token의 audience와 role을 API가 따로 검증해 결정한다.
app-a가 된 상태에서도 app-b client와 API client·role·audience는 아직 없다. 두 묶음을 따로 적용하면 “다시 로그인하지 않음”과 “API가 허용함”이 서로 다른 결과임을 확인할 수 있다.
이 장에서 처음 나오는 말3개
audience- 이 access token을 받을 대상으로 발급된 API를 나타내는 aud claim.
realm role- realm 범위 권한 라벨. 이 실습 API는 realm_access.roles에서 읽는다.
앱 session- 각 앱이 access token과 로그인 상태를 보관하는 자체 cookie session. Keycloak SSO session과 별개다.
앱 B에서 SSO를 확인한다
섹션 제목: “앱 B에서 SSO를 확인한다”app-b.json은
app-a와 별도 secret·callback을 가진다. 적용 시 API container는 시작되지 않는다.
./scripts/apply.sh app-b./scripts/verify.sh sso같은 브라우저에서 앱 A에 local-user로 로그인한 뒤 앱 B의 /login을 연다. 앱 B도 authorization
request와 code 교환, 자기 session 생성은 수행하지만 Keycloak은 기존 realm session 때문에 password를
다시 묻지 않는다. 앱 A/B cookie를 서로 공유한 결과가 아니다.
API 설정과 결과를 연결한다
섹션 제목: “API 설정과 결과를 연결한다”다음 공개 원본을 읽는다.
clients/lab-api.json: token을 받기만 하는 bearer-only 대상roles/realm-roles.json:app-user,api-adminmappings/local-user-roles.json: local-user에는 app-user만 유지mappers/api-audience.json: app A/B access token의aud=lab-api
./scripts/apply.sh api./scripts/verify.sh api무토큰 API는 401, local-user의 /api/user는 200, /api/admin은 403이어야 한다. /api/claims에서
검증된 iss, aud, exp, realm_access.roles를 확인한다. 이 JSON은 token 원문이나 Keycloak 전체
사용자 모델이 아니라 api.mjs가
검증한 최소 claim이다.
role을 회수했다 복구한다
섹션 제목: “role을 회수했다 복구한다”- Admin Console의 Users → local-user → Role mapping에서
app-user만 회수한다.default-roles-study와 다른 role은 건드리지 않는다. - 기존 앱 session의 token은 자동으로 교체된다고 가정하지 않는다. 새 private window에서
/login으로 authorization code 교환을 다시 거쳐 새 token을 얻는다. - 새 session의
/api/user가 403인지 확인한다. 기존 token은 만료 전까지 다른 결과일 수 있다. - 공개 원본으로 대상 role을 복구하고 새 로그인으로 200을 확인한다.
./scripts/apply.sh api./scripts/verify.sh api- 같은 브라우저의 Keycloak session이 앱 B password 재입력을 없애지만 앱 B session은 별도로 생긴다.
- API는 서명·issuer·audience·expiration 검증 뒤 role로 403과 200을 가른다.
- role 변경은 이미 발급된 token을 고쳐 쓰지 않으므로 새 로그인의 결과와 구분한다.
다음은 외부 디렉터리 계정 로그인 실습에서 password 원본을 LDAP로 바꾼다.