chore: readme 수정
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
{
|
||||
"version": "1.1",
|
||||
"id": "ap2-mediator-handoff-flow",
|
||||
"title": "AP2 server-held token에서 브라우저 Bearer 요청까지",
|
||||
"question": "AP2에서 AP2_SESSION으로 찾은 server-side authorized client는 어떻게 브라우저의 직접 Bearer API 호출이 되는가?",
|
||||
"type": "sequence",
|
||||
"direction": "LR",
|
||||
"audience": [
|
||||
"token mediator의 custody와 노출 경계를 검토하는 개발자"
|
||||
],
|
||||
"summary": "Mediator는 refresh token을 server-side store에 남기면서 현재 access token만 JSON으로 브라우저에 반환하고, 브라우저가 그 값으로 Resource Server를 직접 호출한다.",
|
||||
"alt": "브라우저, Spring mediator, authorized-client store, Resource Server 사이에서 AP2_SESSION 요청, access-only 응답, 브라우저 Bearer 호출과 JSON 응답이 이어지는 순서도.",
|
||||
"long_description": "브라우저가 AP2_SESSION cookie와 함께 /token/access를 Spring mediator에 요청한다. Mediator는 현재 principal과 keycloak registration으로 authorized-client store에서 token을 조회하고 access token, type, expiry만 응답한다. 브라우저는 access token을 지역 변수로 받아 Authorization Bearer header를 만들고 Resource Server의 /api/me를 직접 호출한 뒤 사용자 JSON을 받는다. Refresh token은 브라우저 응답에 포함되지 않는다.",
|
||||
"source_context": {
|
||||
"document": "document.md",
|
||||
"document_sha256": "df4d1a604c74e756672b5b40510abfedb8c67b39af280a5f51985ea9972f5371",
|
||||
"anchor": {
|
||||
"kind": "marker",
|
||||
"value": "ap2-mediator-handoff-flow",
|
||||
"line": 645
|
||||
}
|
||||
},
|
||||
"composition": {
|
||||
"profile": "sequence",
|
||||
"diagram_only": true,
|
||||
"reference_ids": [
|
||||
"payment-approval-sequence"
|
||||
],
|
||||
"rationale": "Session 요청, authorized-client 조회, access-only 응답, 브라우저 Bearer 호출과 API 응답의 순서가 명시되어 있어 ordered message가 서로 다른 왕복을 가장 명확히 분리한다.",
|
||||
"focus_node": "mediator"
|
||||
},
|
||||
"groups": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "browser",
|
||||
"label": "브라우저",
|
||||
"kind": "participant",
|
||||
"role": "participant",
|
||||
"description": "AP2_SESSION으로 access endpoint를 호출하고 반환된 access token으로 Resource Server를 직접 호출한다.",
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 505,
|
||||
"end_line": 511
|
||||
},
|
||||
{
|
||||
"start_line": 558,
|
||||
"end_line": 586
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "mediator",
|
||||
"label": "Spring mediator",
|
||||
"kind": "participant",
|
||||
"role": "participant",
|
||||
"emphasis": "primary",
|
||||
"description": "현재 principal로 authorized client를 조회하고 access token, type, expiry만 JSON으로 반환한다.",
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 503,
|
||||
"end_line": 540
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "authorized-client-store",
|
||||
"label": "Authorized-client store",
|
||||
"kind": "participant",
|
||||
"role": "participant",
|
||||
"description": "Registration과 principal name으로 access token과 refresh token을 보관하는 process-local service.",
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 445,
|
||||
"end_line": 457
|
||||
},
|
||||
{
|
||||
"start_line": 513,
|
||||
"end_line": 521
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "resource-server",
|
||||
"label": "Resource Server",
|
||||
"kind": "participant",
|
||||
"role": "participant",
|
||||
"description": "브라우저가 만든 Bearer JWT를 검증하고 /api/me 사용자 JSON을 반환한다.",
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 571,
|
||||
"end_line": 599
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "session-request",
|
||||
"from": "browser",
|
||||
"to": "mediator",
|
||||
"label": "GET /token/access + AP2_SESSION",
|
||||
"kind": "request",
|
||||
"order": 1,
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 503,
|
||||
"end_line": 511
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "authorize-client",
|
||||
"from": "mediator",
|
||||
"to": "authorized-client-store",
|
||||
"label": "authorize current principal",
|
||||
"kind": "request",
|
||||
"order": 2,
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 513,
|
||||
"end_line": 521
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "load-access-token",
|
||||
"from": "authorized-client-store",
|
||||
"to": "mediator",
|
||||
"label": "current access token",
|
||||
"kind": "response",
|
||||
"style": "dashed",
|
||||
"order": 3,
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 513,
|
||||
"end_line": 521
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "access-only-response",
|
||||
"from": "mediator",
|
||||
"to": "browser",
|
||||
"label": "access token + type + expiry",
|
||||
"kind": "response",
|
||||
"style": "dashed",
|
||||
"order": 4,
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 523,
|
||||
"end_line": 540
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "bearer-request",
|
||||
"from": "browser",
|
||||
"to": "resource-server",
|
||||
"label": "GET /api/me · browser-created Bearer",
|
||||
"kind": "request",
|
||||
"emphasis": "primary",
|
||||
"order": 5,
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 558,
|
||||
"end_line": 588
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "identity-response",
|
||||
"from": "resource-server",
|
||||
"to": "browser",
|
||||
"label": "subject · username · issuer · audience",
|
||||
"kind": "response",
|
||||
"style": "dashed",
|
||||
"order": 6,
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 590,
|
||||
"end_line": 615
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
}
|
||||
],
|
||||
"legend": [],
|
||||
"metadata": {
|
||||
"rationale": "Refresh token custody와 access token 전달을 혼동하지 않도록 happy-path access handoff의 메시지 순서만 표현했다."
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user