Client를 연결하고 로그인 확인하기
guided base에는 realm과 local-user만 있고 app-a client나 앱 service는 없다. 공개 JSON을 읽고 적용해야
앱이 Authorization Code를 받아 자기 session을 만들 수 있다. 앱 A는 브라우저에서 도는 SPA가 아니라
Node server 앱이라 로그인에는 사용자 브라우저·앱 A server·Keycloak 셋이 참여한다. 이 흐름과 각 값이
막는 공격은 OAuth 2.0과 OIDC 로그인의 다이어그램과 보호 장치 표가 정본이다.
이 장에서 처음 나오는 말2개
redirect URI- Keycloak이 authorization code를 돌려보내도록 client에 미리 허용한 정확한 callback 주소.
PKCEProof Key for Code Exchange- 로그인 시작 시 만든 verifier와 challenge를 code 교환에 묶는 보호 장치.
정상 설정을 적용한다
섹션 제목: “정상 설정을 적용한다”-
./scripts/status.sh에서mode=guided stage=base와 기반 세 service를 확인한다. -
app-a.json을 읽는다. confidential client이고 Standard Flow만 켜며 callback은/callback하나, PKCE는S256이다. -
설정을 적용하고 실제 로그인 흐름을 검사한다.
터미널 창 ./scripts/apply.sh app-a./scripts/verify.sh app-a -
Admin Console의 Clients → app-a → Settings에서 Client authentication, Standard flow, Valid redirect URIs를 공개 JSON과 대조한다.
-
브라우저에서 앱 A
https://app-a.keycloak.test:30081/를 열고 Sign in with Keycloak을 누른다. Keycloak 로그인 화면에local-user와 아래 파일의 비밀번호를 넣는다.터미널 창 cat .state/secrets/keycloak-local-user-password # labs/keycloak에서로그인 뒤 앱 A 화면에 token claims·User API·Admin API 링크가 보이고,
https://app-a.keycloak.test:30081/session이authenticated: true와username: local-user를 반환하면 성공이다.
검사 container는 브라우저 역할로 로그인을 두 번 해 본다. 정상 password는 callback과 앱 session까지 성공해야 하고, 오답은 callback에 도달하지 못하고 로그인 폼으로 돌아와야 한다. 시도마다 새 cookie jar — 브라우저의 cookie 보관함으로, private 창을 새로 여는 것과 같다 — 로 시작해서 이전 로그인의 Keycloak session이 비밀번호 검사를 건너뛰게 하지 않는다. 성공 경로에서는 authorization 요청의 Code·PKCE S256·state·nonce·redirect URI가 공개 JSON·앱 코드와 맞는지 본다. code를 token으로 바꾸는 쪽은 앱 A server라서 client secret은 브라우저 역할인 검사 container에 아예 전달되지 않는다.
redirect를 일부러 깨뜨린다
섹션 제목: “redirect를 일부러 깨뜨린다”keycloak/clients/app-a.json의redirectUris에서/callback을/wrong-callback으로 바꾼다../scripts/apply.sh app-a를 다시 실행한다. 앱 코드는 여전히 원래/callback을 요청한다.- 새 private window에서 앱 A
/login을 열고 Keycloak이 등록되지 않은 redirect를 거부하는지 본다. 기존 앱·Keycloak session을 결과로 재사용하지 않는다. - JSON을 정확한
https://app-a.keycloak.test:30081/callback으로 되돌리고 다시 apply·verify한다.
./scripts/apply.sh app-a./scripts/verify.sh app-awildcard를 넓히거나 HTTPS 검증을 끄는 것은 복구가 아니다. 설정 원본과 앱 callback 계약을 다시 맞춘다.
읽을 코드
섹션 제목: “읽을 코드”server.mjs의
/login, /callback, /session만 이어 읽는다. 첫 route가 transaction을 만들고, callback이 code를
교환해 access token을 앱 session에 넣으며, session endpoint는 token 원문 없이 로그인 결과만 보여 준다.
- client의 flow·PKCE·redirect는 앱이 보내는 authorization request와 정확히 맞아야 한다.
- app-a를 적용하기 전에는 client와 앱 service가 없고, 적용 성공 뒤에만 stage가 올라간다.
- redirect 실패는 wildcard나 TLS 우회가 아니라 공개 JSON을 원래 callback으로 복구해 해결한다.
다음은 두 앱 SSO와 API 권한 실습에서 별도 client의 SSO와 API 인가를 붙인다.