Files
technical-visualization-haness/.work/keycloak-four-patterns/final/assets/ap3-csrf-boundary/ap3-csrf-boundary.drawio
T
2026-07-29 18:03:21 +09:00

52 lines
5.4 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
<diagram id="ap3-csrf-boundary" name="AP3의 masked CSRF 응답과 raw POST credential">
<mxGraphModel dx="1411" dy="392" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1411" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="n_csrf-endpoint" value="BFF · /bff/csrf" tooltip="CookieCsrfTokenRepository와 CsrfController를 통해 raw cookie와 masked JSON 응답을 만드는 endpoint. | Evidence: L819-L844" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="70.0" y="171.5" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_masked-json" value="JSON body · masked&lt;br/&gt;token = XOR/Base64&lt;br/&gt;headerName metadata&lt;br/&gt;POST token 값으로 미사용" tooltip="Request attribute용 token을 masked한 JSON 표현으로, SPA는 token 값이 아니라 headerName만 사용한다. | Evidence: L836-L846" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;shape=document;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="380.0" y="60.0" width="220.0" height="110.0" as="geometry"/>
</mxCell>
<mxCell id="n_raw-cookie" value="Browser cookie · raw&lt;br/&gt;XSRF-TOKEN&lt;br/&gt;JavaScript-readable&lt;br/&gt;실제 header data source" tooltip="Cookie repository가 path /에 설정하며 SPA가 document.cookie로 읽는 raw CSRF token. | Evidence: L827-L834, L844-L856" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="399.5" y="242.0" width="181.0" height="105.0" as="geometry"/>
</mxCell>
<mxCell id="n_post-assembler" value="SPA POST 조립&lt;br/&gt;Cookie 자동 첨부&lt;br/&gt;document.cookie raw → header&lt;br/&gt;JSON headerName만 사용" tooltip="Raw cookie 값을 X-XSRF-TOKEN header에 넣어 preference POST를 만드는 browser code. | Evidence: L846-L856, L862-L870" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="760.0" y="151.0" width="230.0" height="105.0" as="geometry"/>
</mxCell>
<mxCell id="n_csrf-filter" value="Spring CSRF filter&lt;br/&gt;raw cookie = raw header 비교&lt;br/&gt;일치 → controller&lt;br/&gt;부재·불일치 → 403" tooltip="Repository의 expected raw token과 submitted raw header를 controller 실행 전에 비교하는 방어선. | Evidence: L854-L854, L873-L873, L897-L904" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="1150.0" y="151.0" width="216.0" height="105.0" as="geometry"/>
</mxCell>
<mxCell id="e_assembler-to-filter" value="Cookie raw = Header raw" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_post-assembler" target="n_csrf-filter">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1070.0" y="175.5" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_endpoint-to-masked-json" value="masked JSON" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_csrf-endpoint" target="n_masked-json">
<mxGeometry relative="1" as="geometry">
<mxPoint x="324.0" y="154.8" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_endpoint-to-raw-cookie" value="Set-Cookie · raw" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_csrf-endpoint" target="n_raw-cookie">
<mxGeometry relative="1" as="geometry">
<mxPoint x="333.8" y="253.5" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_masked-json-to-assembler" value="headerName only" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_masked-json" target="n_post-assembler">
<mxGeometry relative="1" as="geometry">
<mxPoint x="704.0" y="154.8" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_raw-cookie-to-assembler" value="document.cookie · raw" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_raw-cookie" target="n_post-assembler">
<mxGeometry relative="1" as="geometry">
<mxPoint x="694.2" y="253.5" as="offset"/>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>