Files
document-haness/.playwright-mcp/page-2026-08-26T11-37-37-222Z.yml
T

429 lines
32 KiB
YAML

- generic [ref=f11e3]:
- link "본문으로 건너뛰기" [ref=f11e4] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f11e5]:
- generic [ref=f11e6]:
- link "TechLog Studio" [ref=f11e7] [cursor=pointer]:
- /url: /studio
- text: TechLog
- generic [ref=f11e8]: Studio
- navigation "Studio 주 탐색" [ref=f11e10]:
- link "작업본" [ref=f11e11] [cursor=pointer]:
- /url: /studio/documents
- link "게시 기록" [ref=f11e12] [cursor=pointer]:
- /url: /studio/publications
- link "새 문서" [ref=f11e13] [cursor=pointer]:
- /url: /studio/documents/new
- link "주제·프로젝트" [ref=f11e14] [cursor=pointer]:
- /url: /studio/taxonomy
- link "릴리즈" [ref=f11e15] [cursor=pointer]:
- /url: /studio/releases
- link "공개 사이트 보기" [ref=f11e16] [cursor=pointer]:
- /url: /
- button "로그아웃" [ref=f11e17]
- main [ref=f11e18]:
- generic [ref=f11e19]:
- generic [ref=f11e20]:
- region [ref=f11e21]:
- generic [ref=f11e22]:
- paragraph [ref=f11e23]: REFERENCE · VERSION 13
- heading "문서 편집" [level=1] [ref=f11e24]
- paragraph [ref=f11e25]: Public Client와 Confidential Client 구분 기준
- region [ref=f11e26]:
- generic [ref=f11e27]:
- paragraph [ref=f11e28]: DOCUMENT
- heading "기본 정보" [level=2] [ref=f11e29]
- generic [ref=f11e30]:
- generic [ref=f11e31]:
- generic [ref=f11e32]: 제목
- textbox "제목" [ref=f11e33]: Public Client와 Confidential Client 구분 기준
- generic [ref=f11e34]:
- generic [ref=f11e35]: slug
- textbox "slug" [ref=f11e36]:
- /placeholder: 비우면 제목에서 만듭니다 (영문 소문자·숫자·하이픈)
- text: public-confidential-client-boundary
- generic [ref=f11e37]:
- generic [ref=f11e38]: 요약
- textbox "요약" [ref=f11e39]: client 종류는 secret을 안전하게 보관할 수 있는지로 정한다. SPA는 보관할 곳이 없어 public client로 등록한다. 종류는 secret이 어디 있는지를 말할 뿐이고, 브라우저에 token이 가는지는 따로 정해진다.
- generic [ref=f11e40]:
- generic [ref=f11e41]: Topic
- combobox "Topic" [ref=f11e42]:
- option "선택하지 않음"
- option "OAuth/OIDC 인증 경계" [selected]
- generic [ref=f11e43]:
- generic [ref=f11e44]: Project
- combobox "Project" [ref=f11e45]:
- option "미지정"
- option "Backend Clean Architecture"
- option "KeyCloak Patterns" [selected]
- option "Liner N + 1문제"
- group "관계" [ref=f11e46]:
- generic [ref=f11e48]:
- generic [ref=f11e49]:
- generic [ref=f11e50]: 관계 1 대상
- combobox "관계 1 대상" [ref=f11e51]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준" [disabled]
- option "BFF 인증 구조 설계 기준"
- option "BFF가 OAuth Token을 관리하는 조건"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정"
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유"
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건"
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준"
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출" [disabled]
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계" [selected]
- generic [ref=f11e52]:
- generic [ref=f11e53]: 관계 1 이유
- textbox "관계 1 이유" [ref=f11e54]: SPA를 public client로 등록한 이유를 실제 구성에서 확인할 수 있다.
- generic [ref=f11e55]:
- button "위로" [disabled] [ref=f11e56]
- button "아래로" [ref=f11e57]
- button "삭제" [ref=f11e58]
- generic [ref=f11e59]:
- generic [ref=f11e60]:
- generic [ref=f11e61]: 관계 2 대상
- combobox "관계 2 대상" [ref=f11e62]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준" [disabled]
- option "BFF 인증 구조 설계 기준"
- option "BFF가 OAuth Token을 관리하는 조건"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정"
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유"
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건"
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준"
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출" [selected]
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계" [disabled]
- generic [ref=f11e63]:
- generic [ref=f11e64]: 관계 2 이유
- textbox "관계 2 이유" [ref=f11e65]: confidential client를 사용해도 access token 전달 방식은 별도로 설계된다는 예다.
- generic [ref=f11e66]:
- button "위로" [ref=f11e67]
- button "아래로" [ref=f11e68]
- button "삭제" [ref=f11e69]
- generic [ref=f11e70]:
- generic [ref=f11e71]:
- generic [ref=f11e72]: 관계 3 대상
- combobox "관계 3 대상" [ref=f11e73]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준" [selected]
- option "BFF 인증 구조 설계 기준"
- option "BFF가 OAuth Token을 관리하는 조건"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정"
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유"
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건"
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준"
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출" [disabled]
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계" [disabled]
- generic [ref=f11e74]:
- generic [ref=f11e75]: 관계 3 이유
- textbox "관계 3 이유" [ref=f11e76]: client 종류에 따라 token endpoint의 client 인증 방식이 달라진다.
- generic [ref=f11e77]:
- button "위로" [ref=f11e78]
- button "아래로" [disabled] [ref=f11e79]
- button "삭제" [ref=f11e80]
- button "관계 추가" [ref=f11e81]
- region [ref=f11e82]:
- generic [ref=f11e83]:
- paragraph [ref=f11e84]: REFERENCE
- heading "재사용할 기준" [level=2] [ref=f11e85]
- generic [ref=f11e86]:
- generic [ref=f11e87]: 목적
- textbox "목적" [ref=f11e88]: client 종류를 무엇으로 정하는지부터 맞춰야 PKCE와 client 인증을 어디에 둘지 정할 수 있게 된다. 기준은 프레임워크나 언어가 아니라 값이 도달하는 범위다. 브라우저에서 실행되는 코드에 넣은 값은 개발자 도구를 열면 그대로 보이기 때문에 SPA는 secret을 가질 수 없고, server와 BFF는 그 값을 process 밖으로 내보내지 않을 수 있어서 secret을 들고 있게 된다. 여기서 자주 섞이는 것이 하나 있는데, 종류가 confidential이어도 브라우저에 token이 갈 수 있다. 서로 다른 결정이라서 따로 답해야 한다.
- group "규칙" [ref=f11e89]:
- generic [ref=f11e91]:
- generic [ref=f11e92]:
- generic [ref=f11e93]: 규칙 1 제목
- textbox "규칙 1 제목" [ref=f11e94]: secret을 숨길 수 있는지로 종류를 정한다
- generic [ref=f11e95]:
- generic [ref=f11e96]: 규칙 1 본문
- textbox "규칙 1 본문" [ref=f11e97]: 배포물이나 실행 중 memory에서 사용자가 값을 꺼낼 수 있으면 public client가 되고, server 안에만 두고 응답으로 나가지 않게 할 수 있으면 confidential client다. native app은 브라우저가 아니지만 배포물을 뜯으면 값이 나오기 때문에 여기서도 public client로 다루게 된다. 실행 환경의 이름이 아니라 값이 어디까지 가는지로 정한다.
- generic [ref=f11e98]:
- button "위로" [disabled] [ref=f11e99]
- button "아래로" [ref=f11e100]
- button "삭제" [ref=f11e101]
- generic [ref=f11e102]:
- generic [ref=f11e103]:
- generic [ref=f11e104]: 규칙 2 제목
- textbox "규칙 2 제목" [ref=f11e105]: public client에서도 Authorization Code Flow에 PKCE를 함께 쓴다
- generic [ref=f11e106]:
- generic [ref=f11e107]: 규칙 2 본문
- textbox "규칙 2 본문" [ref=f11e108]: PKCE는 client secret을 대체하는 client 인증 방식이 아니다. authorization request에서 만든 verifier와 token request의 verifier를 연결해 탈취된 authorization code의 교환을 어렵게 만든다. 여기서 S256을 쓴다. plain은 challenge가 verifier 그대로라서 중간에서 본 사람이 그대로 쓸 수 있다.
- generic [ref=f11e109]:
- button "위로" [ref=f11e110]
- button "아래로" [ref=f11e111]
- button "삭제" [ref=f11e112]
- generic [ref=f11e113]:
- generic [ref=f11e114]:
- generic [ref=f11e115]: 규칙 3 제목
- textbox "규칙 3 제목" [ref=f11e116]: confidential client에도 PKCE를 함께 쓸 수 있다
- generic [ref=f11e117]:
- generic [ref=f11e118]: 규칙 3 본문
- textbox "규칙 3 본문" [ref=f11e119]: client 인증이 있어도 PKCE는 여전히 쓸모가 있다. 두 장치가 막는 구간이 서로 달라서 함께 두면 그만큼 좁아지게 된다. 다만 「Authorization Code를 쓴다」와 「PKCE S256까지 설정으로 고정했다」는 서로 다른 주장이다. 설정과 테스트에서 확인한 범위까지만 말할 수 있다.
- generic [ref=f11e120]:
- button "위로" [ref=f11e121]
- button "아래로" [ref=f11e122]
- button "삭제" [ref=f11e123]
- generic [ref=f11e124]:
- generic [ref=f11e125]:
- generic [ref=f11e126]: 규칙 4 제목
- textbox "규칙 4 제목" [ref=f11e127]: public client에서는 implicit flow와 direct access grant를 끈다
- generic [ref=f11e128]:
- generic [ref=f11e129]: 규칙 4 본문
- textbox "규칙 4 본문" [ref=f11e130]: implicit flow는 token을 redirect fragment로 받게 되어서 주소창과 히스토리에 token이 남고, direct access grant는 애플리케이션이 사용자의 아이디와 비밀번호를 직접 받게 되어서 IdP만 알면 되는 값을 애플리케이션이 만지게 된다. 현재 예제에서는 Authorization Code Flow를 사용하므로 implicit flow와 direct access grant를 비활성화했다.
- generic [ref=f11e131]:
- button "위로" [ref=f11e132]
- button "아래로" [ref=f11e133]
- button "삭제" [ref=f11e134]
- generic [ref=f11e135]:
- generic [ref=f11e136]:
- generic [ref=f11e137]: 규칙 5 제목
- textbox "규칙 5 제목" [ref=f11e138]: 종류가 곧 브라우저 token 유무는 아니다
- generic [ref=f11e139]:
- generic [ref=f11e140]: 규칙 5 본문
- textbox "규칙 5 본문" [ref=f11e141]: confidential client가 code를 교환해도 그 결과인 access token을 응답 본문으로 브라우저에 건넬 수 있고, 실제로 그렇게 도는 구조가 있다. 종류는 secret을 어디에 두는지를 말하고, token 노출은 어느 계층이 API를 부르는지에 따라 갈린다.
- generic [ref=f11e142]:
- button "위로" [ref=f11e143]
- button "아래로" [disabled] [ref=f11e144]
- button "삭제" [ref=f11e145]
- button "규칙 추가" [ref=f11e146]
- group "적용 조건" [ref=f11e147]:
- generic [ref=f11e149]:
- generic [ref=f11e150]:
- generic [ref=f11e151]: 적용 조건 1
- textbox "적용 조건 1" [ref=f11e152]: 새 OAuth client를 등록할 때
- generic [ref=f11e153]:
- button "위로" [disabled] [ref=f11e154]
- button "아래로" [ref=f11e155]
- button "삭제" [ref=f11e156]
- generic [ref=f11e157]:
- generic [ref=f11e158]:
- generic [ref=f11e159]: 적용 조건 2
- textbox "적용 조건 2" [ref=f11e160]: SPA와 server 중 어디가 code를 교환할지 정할 때
- generic [ref=f11e161]:
- button "위로" [ref=f11e162]
- button "아래로" [ref=f11e163]
- button "삭제" [ref=f11e164]
- generic [ref=f11e165]:
- generic [ref=f11e166]:
- generic [ref=f11e167]: 적용 조건 3
- textbox "적용 조건 3" [ref=f11e168]: PKCE와 client 인증을 어디에 둘지 정할 때
- generic [ref=f11e169]:
- button "위로" [ref=f11e170]
- button "아래로" [ref=f11e171]
- button "삭제" [ref=f11e172]
- generic [ref=f11e173]:
- generic [ref=f11e174]:
- generic [ref=f11e175]: 적용 조건 4
- textbox "적용 조건 4" [ref=f11e176]: 기존 client의 종류가 맞는지 다시 볼 때
- generic [ref=f11e177]:
- button "위로" [ref=f11e178]
- button "아래로" [disabled] [ref=f11e179]
- button "삭제" [ref=f11e180]
- button "적용 조건 추가" [ref=f11e181]
- group "예외" [ref=f11e182]:
- generic [ref=f11e184]:
- generic [ref=f11e185]:
- generic [ref=f11e186]: 예외 1
- textbox "예외 1" [ref=f11e187]: 같은 서비스가 브라우저용 public client와 server용 confidential client를 따로 등록할 수 있다. 하나로 합치려고 secret을 브라우저로 내보내지는 않는다.
- generic [ref=f11e188]:
- button "위로" [disabled] [ref=f11e189]
- button "아래로" [ref=f11e190]
- button "삭제" [ref=f11e191]
- generic [ref=f11e192]:
- generic [ref=f11e193]:
- generic [ref=f11e194]: 예외 2
- textbox "예외 2" [ref=f11e195]: backend가 사용자 없이 자기 자격으로 부르는 흐름은 Client Credentials를 쓰는 별도 client다.
- generic [ref=f11e196]:
- button "위로" [ref=f11e197]
- button "아래로" [disabled] [ref=f11e198]
- button "삭제" [ref=f11e199]
- button "예외 추가" [ref=f11e200]
- group "예시" [ref=f11e201]:
- generic [ref=f11e203]:
- generic [ref=f11e204]:
- generic [ref=f11e205]: 예시 1
- textbox "예시 1" [ref=f11e206]: "SPA용 client : public, standard flow만 켜고 implicit flow와 direct grant는 끈다"
- generic [ref=f11e207]:
- button "위로" [disabled] [ref=f11e208]
- button "아래로" [ref=f11e209]
- button "삭제" [ref=f11e210]
- generic [ref=f11e211]:
- generic [ref=f11e212]:
- generic [ref=f11e213]: 예시 2
- textbox "예시 2" [ref=f11e214]: "Mediator용 client : confidential, client_secret_basic으로 token endpoint에서 인증한다"
- generic [ref=f11e215]:
- button "위로" [ref=f11e216]
- button "아래로" [ref=f11e217]
- button "삭제" [ref=f11e218]
- generic [ref=f11e219]:
- generic [ref=f11e220]:
- generic [ref=f11e221]: 예시 3
- textbox "예시 3" [ref=f11e222]: "BFF용 client : confidential, PKCE S256을 함께 쓴다"
- generic [ref=f11e223]:
- button "위로" [ref=f11e224]
- button "아래로" [ref=f11e225]
- button "삭제" [ref=f11e226]
- generic [ref=f11e227]:
- generic [ref=f11e228]:
- generic [ref=f11e229]: 예시 4
- textbox "예시 4" [ref=f11e230]: "Proxy용 client : confidential, oauth2-proxy가 secret과 verifier로 code를 교환한다"
- generic [ref=f11e231]:
- button "위로" [ref=f11e232]
- button "아래로" [ref=f11e233]
- button "삭제" [ref=f11e234]
- generic [ref=f11e235]:
- generic [ref=f11e236]:
- generic [ref=f11e237]: 예시 5
- textbox "예시 5" [ref=f11e238]: confidential client인 Mediator를 써도 access token은 브라우저 응답에 실릴 수 있다
- generic [ref=f11e239]:
- button "위로" [ref=f11e240]
- button "아래로" [disabled] [ref=f11e241]
- button "삭제" [ref=f11e242]
- button "예시 추가" [ref=f11e243]
- generic [ref=f11e244]:
- generic [ref=f11e245]: 마지막 검증일
- textbox "마지막 검증일" [ref=f11e246]
- region [ref=f11e247]:
- generic [ref=f11e248]:
- paragraph [ref=f11e249]: LIVE
- heading "즉시 미리보기" [level=2] [ref=f11e250]
- generic [ref=f11e253]:
- generic [ref=f11e254]:
- navigation "문서 경로" [ref=f11e255]:
- link "Reference" [ref=f11e256] [cursor=pointer]:
- /url: /explore/references
- generic [ref=f11e257]: /
- generic [ref=f11e258]: OAuth/OIDC 인증 경계
- generic [ref=f11e259]: /
- link "KeyCloak Patterns" [ref=f11e260] [cursor=pointer]:
- /url: /projects/keycloak-patterns
- heading "Public Client와 Confidential Client 구분 기준" [level=1] [ref=f11e261]
- paragraph [ref=f11e262]: client 종류는 secret을 안전하게 보관할 수 있는지로 정한다. SPA는 보관할 곳이 없어 public client로 등록한다. 종류는 secret이 어디 있는지를 말할 뿐이고, 브라우저에 token이 가는지는 따로 정해진다.
- generic [ref=f11e263]:
- generic [ref=f11e264]:
- term [ref=f11e265]: 유형
- definition [ref=f11e266]: Reference
- generic [ref=f11e267]:
- term [ref=f11e268]: 프로젝트
- definition [ref=f11e269]: KeyCloak Patterns
- generic [ref=f11e270]:
- term [ref=f11e271]: 게시
- definition [ref=f11e272]: 게시 전
- region [ref=f11e273]:
- paragraph [ref=f11e274]: Purpose
- heading "이 기준을 쓰는 이유" [level=2] [ref=f11e275]
- paragraph [ref=f11e276]: client 종류를 무엇으로 정하는지부터 맞춰야 PKCE와 client 인증을 어디에 둘지 정할 수 있게 된다.기준은 프레임워크나 언어가 아니라 값이 도달하는 범위다. 브라우저에서 실행되는 코드에 넣은 값은 개발자 도구를 열면 그대로 보이기 때문에 SPA는 secret을 가질 수 없고, server와 BFF는 그 값을 process 밖으로 내보내지 않을 수 있어서 secret을 들고 있게 된다.여기서 자주 섞이는 것이 하나 있는데, 종류가 confidential이어도 브라우저에 token이 갈 수 있다. 서로 다른 결정이라서 따로 답해야 한다.
- article [ref=f11e277]:
- region [ref=f11e278]:
- heading "판단 기준" [level=2] [ref=f11e279]
- list [ref=f11e280]:
- listitem [ref=f11e281]:
- generic [ref=f11e282]: "01"
- generic [ref=f11e283]:
- heading "secret을 숨길 수 있는지로 종류를 정한다" [level=3] [ref=f11e284]
- paragraph [ref=f11e285]: 배포물이나 실행 중 memory에서 사용자가 값을 꺼낼 수 있으면 public client가 되고, server 안에만 두고 응답으로 나가지 않게 할 수 있으면 confidential client다. native app은 브라우저가 아니지만 배포물을 뜯으면 값이 나오기 때문에 여기서도 public client로 다루게 된다. 실행 환경의 이름이 아니라 값이 어디까지 가는지로 정한다.
- listitem [ref=f11e286]:
- generic [ref=f11e287]: "02"
- generic [ref=f11e288]:
- heading "public client에서도 Authorization Code Flow에 PKCE를 함께 쓴다" [level=3] [ref=f11e289]
- paragraph [ref=f11e290]: PKCE는 client secret을 대체하는 client 인증 방식이 아니다. authorization request에서 만든 verifier와 token request의 verifier를 연결해 탈취된 authorization code의 교환을 어렵게 만든다. 여기서 S256을 쓴다. plain은 challenge가 verifier 그대로라서 중간에서 본 사람이 그대로 쓸 수 있다.
- listitem [ref=f11e291]:
- generic [ref=f11e292]: "03"
- generic [ref=f11e293]:
- heading "confidential client에도 PKCE를 함께 쓸 수 있다" [level=3] [ref=f11e294]
- paragraph [ref=f11e295]: client 인증이 있어도 PKCE는 여전히 쓸모가 있다. 두 장치가 막는 구간이 서로 달라서 함께 두면 그만큼 좁아지게 된다. 다만 「Authorization Code를 쓴다」와 「PKCE S256까지 설정으로 고정했다」는 서로 다른 주장이다. 설정과 테스트에서 확인한 범위까지만 말할 수 있다.
- listitem [ref=f11e296]:
- generic [ref=f11e297]: "04"
- generic [ref=f11e298]:
- heading "public client에서는 implicit flow와 direct access grant를 끈다" [level=3] [ref=f11e299]
- paragraph [ref=f11e300]: implicit flow는 token을 redirect fragment로 받게 되어서 주소창과 히스토리에 token이 남고, direct access grant는 애플리케이션이 사용자의 아이디와 비밀번호를 직접 받게 되어서 IdP만 알면 되는 값을 애플리케이션이 만지게 된다. 현재 예제에서는 Authorization Code Flow를 사용하므로 implicit flow와 direct access grant를 비활성화했다.
- listitem [ref=f11e301]:
- generic [ref=f11e302]: "05"
- generic [ref=f11e303]:
- heading "종류가 곧 브라우저 token 유무는 아니다" [level=3] [ref=f11e304]
- paragraph [ref=f11e305]: confidential client가 code를 교환해도 그 결과인 access token을 응답 본문으로 브라우저에 건넬 수 있고, 실제로 그렇게 도는 구조가 있다. 종류는 secret을 어디에 두는지를 말하고, token 노출은 어느 계층이 API를 부르는지에 따라 갈린다.
- region [ref=f11e306]:
- heading "적용할 때" [level=2] [ref=f11e307]
- list [ref=f11e308]:
- listitem [ref=f11e309]: 새 OAuth client를 등록할 때
- listitem [ref=f11e310]: SPA와 server 중 어디가 code를 교환할지 정할 때
- listitem [ref=f11e311]: PKCE와 client 인증을 어디에 둘지 정할 때
- listitem [ref=f11e312]: 기존 client의 종류가 맞는지 다시 볼 때
- region [ref=f11e313]:
- heading "예외와 주의" [level=2] [ref=f11e314]
- list [ref=f11e315]:
- listitem [ref=f11e316]: 같은 서비스가 브라우저용 public client와 server용 confidential client를 따로 등록할 수 있다. 하나로 합치려고 secret을 브라우저로 내보내지는 않는다.
- listitem [ref=f11e317]: backend가 사용자 없이 자기 자격으로 부르는 흐름은 Client Credentials를 쓰는 별도 client다.
- region [ref=f11e318]:
- heading "예시" [level=2] [ref=f11e319]
- list [ref=f11e320]:
- listitem [ref=f11e321]: "SPA용 client : public, standard flow만 켜고 implicit flow와 direct grant는 끈다"
- listitem [ref=f11e322]: "Mediator용 client : confidential, client_secret_basic으로 token endpoint에서 인증한다"
- listitem [ref=f11e323]: "BFF용 client : confidential, PKCE S256을 함께 쓴다"
- listitem [ref=f11e324]: "Proxy용 client : confidential, oauth2-proxy가 secret과 verifier로 code를 교환한다"
- listitem [ref=f11e325]: confidential client인 Mediator를 써도 access token은 브라우저 응답에 실릴 수 있다
- paragraph [ref=f11e326]: 마지막 검증
- region [ref=f11e327]:
- paragraph [ref=f11e328]: Relations
- heading "이 기록과 연결된 맥락" [level=2] [ref=f11e329]
- list [ref=f11e330]:
- listitem [ref=f11e331]:
- link "SPA를 public client로 등록한 이유를 실제 구성에서 확인할 수 있다. SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계" [ref=f11e332] [cursor=pointer]:
- /url: /cases/spa-browser-credential-boundary
- generic [ref=f11e333]: SPA를 public client로 등록한 이유를 실제 구성에서 확인할 수 있다.
- strong [ref=f11e334]: SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계
- generic [ref=f11e335]:
- listitem [ref=f11e336]:
- link "confidential client를 사용해도 access token 전달 방식은 별도로 설계된다는 예다. Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출" [ref=f11e337] [cursor=pointer]:
- /url: /cases/split-custody-access-token
- generic [ref=f11e338]: confidential client를 사용해도 access token 전달 방식은 별도로 설계된다는 예다.
- strong [ref=f11e339]: Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출
- generic [ref=f11e340]:
- listitem [ref=f11e341]:
- link "client 종류에 따라 token endpoint의 client 인증 방식이 달라진다. Authorization Code Flow의 Endpoint와 Credential 이동 기준" [ref=f11e342] [cursor=pointer]:
- /url: /references/authorization-code-endpoint-credential-movement
- generic [ref=f11e343]: client 종류에 따라 token endpoint의 client 인증 방식이 달라진다.
- strong [ref=f11e344]: Authorization Code Flow의 Endpoint와 Credential 이동 기준
- generic [ref=f11e345]:
- complementary [ref=f11e346]:
- heading "작업 상태" [level=2] [ref=f11e347]
- status "편집 상태" [ref=f11e348]: 저장됨
- generic [ref=f11e349]:
- generic [ref=f11e350]:
- term [ref=f11e351]: 저장 버전
- definition [ref=f11e352]: "13"
- generic [ref=f11e353]:
- term [ref=f11e354]: 종류
- definition [ref=f11e355]: REFERENCE
- paragraph [ref=f11e356]: 불완전한 초안도 저장할 수 있습니다. Ctrl+S 로도 저장합니다. 게시를 누르면 채워야 할 칸을 그 자리에 표시합니다.
- generic [ref=f11e357]:
- button "저장" [disabled] [ref=f11e358]
- button "게시" [ref=f11e359]
- paragraph [ref=f11e360]: 버전 13으로 저장했습니다.