세션 및 보안
문서 세션 및 접근 제어
Doconut 토큰은 강력합니다: 바인딩되지 않은 경우 토큰을 제시하는 사람은 문서의 모든 페이지를 요청할 수 있습니다. 이 페이지에서는 세션이 무엇을 보유하고 있는지, 얼마나 오래 지속되는지, UseDoconut()이 기본적으로 활성화하는 검증을 설명합니다.
문서 세션이 보유하는 내용
각 성공적인 OpenDocumentAsync 호출은 IMemoryCache에 하나의 세션을 생성합니다:
- 로드된 포맷 뷰어(파싱된 문서를 보유하는 문서 엔진 인스턴스),
- 페이지별 상태 — 회전, 플립 및 사용자가 위젯에서 적용하는 주석 데이터,
- 선택적인 검색 인덱스, 첫 검색 시 지연 로드되거나 페이지가 공유 저장소에서 제공될 때 미리 만든
.srh파일에서 로드됩니다, DocOptions.Watermark에서 가져온 세션 워터마크.
수명
세션은 슬라이딩 윈도우 방식으로 만료됩니다: DocOptions.TimeOut 분(기본 60) 동안 토큰을 제시하는 모든 요청이 있을 때마다 타이머가 재설정됩니다. 세션이 만료되거나 CloseDocument(token)에 의해 퇴거될 경우, 퇴거 콜백이 문서 엔진을 폐기하고 연관된 메모리를 즉시 해제합니다.
// 한 번의 미리보기를 위한 단기간 세션
var token = await viewer.OpenDocumentAsync(path, new DocOptions { TimeOut = 10 });만료된 토큰으로 요청하면 Document session not found. Please re-open document. 라는 오류 이미지가 반환됩니다 — 클라이언트는 새 토큰을 얻기 위해 문서를 다시 열어야 합니다.
내장 토큰 바인딩
UnsafeMode = false(기본값)인 경우, OpenDocumentAsync는 새 토큰을 해당 요청을 연 ASP.NET 세션에 바인딩하고, 해당 세션에 secure-{token} 마커를 기록합니다. 이후 Doconut 미들웨어는 다른 브라우저 세션에서 토큰을 사용하려는 경우 페이지 제공을 거부합니다:
- 도난당한 토큰을 제시하는 다른 브라우저/세션 → 오류 이미지
You Are Not Authorized To View This Page. - 세션 미들웨어가 등록되지 않음 → HTTP 500
Session middleware not configured. Call UseSession() before UseDoconut().
이 때문에 Quick Start에서는 Doconut 브랜치 앞에 AddSession()과 app.UseSession()을 반드시 호출하도록 권장합니다. 두 가지 실용적인 결과:
- 클라이언트는 페이지 요청 시 ASP.NET 세션 쿠키를 함께 전송해야 합니다. 쿠키를 제거하는 크로스 오리진 설정이나 쿠키 저장소가 없는 API 클라이언트는 검증에 실패합니다 — 이는 버그가 아니라 의도된 동작입니다.
options.UnsafeMode = true로 설정하면 바인딩이 완전히 비활성화됩니다. 이는 제어된 시나리오를 위해 존재하므로, 단일 노드 프로덕션에서는false로 유지하십시오.
주의할 점: 이전 .NET Standard 라이브러리에서는 이 속성을 UnSafeMode 라고 했으며 미들웨어에 전달되었습니다; 여기서는 UnsafeMode 로 이름이 바뀌고 AddDoconut() 내부에서 한 번 설정됩니다.
토큰 바인딩은 전역 UnsafeMode 스위치에 의해만 제어됩니다 — 기본값은 활성(UnsafeMode = false)이며 모든 세션에 적용됩니다. 문서별로 해제할 수 있는 옵션은 없으며, UnsafeMode = true 로 설정하면 전역적으로 바인딩이 비활성화됩니다.
접근 권한 부여 및 인증된 사용자
UnsafeMode가 false일 때 UseDoconut()은 페이지 미들웨어 앞에 문서 접근 미들웨어를 자동으로 삽입합니다. 두 번 등록하지 마십시오. 요청에 토큰이 포함되면, 문서를 열 때 기록된 접근 권한 부여를 조회하고 다음 조건이 모두 충족될 때만 허용합니다:
- 토큰에 대한 권한 부여가 존재함,
- 권한 부여가 만료되지 않음(권한 부여 수명 = 문서의
TimeOut), - 요청한 ASP.NET 세션 ID가 문서를 연 세션 ID와 일치함,
- 문서를 연 사용자가 인증된 경우, 요청 사용자의
NameIdentifier클레임도 일치함.
검증에 실패하면 403을 반환합니다 — 페이지/썸네일 요청 시 PNG 오류 이미지, 그 외 경우는 일반 텍스트. 메시지와 토큰 쿼리 키는 DocumentSecurityOptions(TokenQueryKey 기본값 "token"; UnauthorizedMessage 기본값 "You Are Not Authorized To View This Page.")에서 가져옵니다. 앱을 빌드하기 전에 ASP.NET Core DI를 통해 해당 옵션을 구성하십시오. 세션 상태를 사용할 수 없을 경우 미들웨어는 HTTP 500으로 차단됩니다: ASP.NET Session is required for Doconut document security.
builder.Services.Configure<Doconut.Security.DocumentSecurityOptions>(options =>
{
options.TokenQueryKey = "token";
options.UnauthorizedMessage = "You Are Not Authorized To View This Page.";
});핵심 페이지 미들웨어는 문서를 제공하기 전에 secure-{token} 세션 마커를 확인합니다. UnsafeMode = true이면 UseDoconut()은 접근 미들웨어를 건너뛰고 핵심 마커 검증도 비활성화됩니다.
여러 노드에서의 보안
세션에 바인딩된 토큰은 페이지를 제공하는 노드가 문서를 연 요청도 함께 처리했다고 가정합니다. 공유 저장소에서 여러 노드가 동일한 문서를 제공하는 경우, 페이지 요청이 문서를 연 적이 없는 노드에 도달할 수 있어 세션 검증에 의해 거부됩니다.
해답은 문서를 보호하지 않는 것이 아니라, AddDoconutDistributedDocumentSecurity(...)를 통해 서명된 접근 티켓을 사용하는 것입니다. 이는 세션 검증을 각 노드가 독립적으로 검증할 수 있는 자격 증명으로 대체합니다. 전체 구성은 분산 배포 문서를 참고하십시오.
폐기
CloseDocument(token)은 메모리를 해제할 뿐만 아니라 secure-{token} 마커를 제거하고 접근 권한 부여를 폐기합니다. 따라서 폐기된 토큰은 두 보안 레이어 모두에서 즉시 무효화됩니다.
프로덕션 체크리스트
- 단일 노드에서는
UnsafeMode = false(기본값)를 유지하십시오 — 이 전역 스위치가 토큰을 세션에 바인딩합니다. AddDistributedMemoryCache()(MVC 및 Razor Pages 앱은 이미 포함)와AddSession()을 등록하고, Doconut 미들웨어 브랜치 앞에app.UseSession()을 호출하십시오.- 세션 쿠키 정책이 위젯 요청이 쿠키를 전송하도록 허용하는지 확인하십시오(
SameSite, HTTPS 등). - 사용자가 문서를 떠날 때
CloseDocument를 호출하여 메모리와 보안을 모두 확보하십시오. - 토큰을 절대 로그에 남기거나 공유하지 마십시오; 단기간 자격 증명으로 취급하십시오.
- 공유 저장소에서 제공하고 있습니까? 보호되지 않은 문서를 수용하지 말고 서명된 접근 티켓으로 전환하십시오.
이 페이지가 도움이 되었나요?