세션 및 보안
문서 세션 및 액세스 제어
Doconut 토큰은 열려 있는 문서를 식별합니다. 이 토큰을 포함한 요청이 처리되면, 토큰을 얻은 사람은 모든 페이지를 읽을 수 있습니다. 이 페이지에서는 문서 세션이 무엇을 보유하고 있는지, 세션이 얼마나 오래 지속되는지, 그리고 DocImage.axd가 어떤 사용자가 페이지를 볼 수 있는지(단일 서버 및 웹 팜 환경에서) 결정하는 방식을 설명합니다.
문서 세션이 보유하는 내용
각 성공적인 OpenDocumentAsync 호출은 메모리에 보관되는 하나의 세션을 생성합니다:
- 로드된 포맷 뷰어 — 파싱된 문서를 보유하고 있는 엔진 인스턴스,
- 페이지별 상태 — 회전, 뒤집기 및 사용자가 위젯에서 적용하는 주석 데이터,
- 선택적인 검색 인덱스 — 첫 번째 검색 시 생성되며(또는 미리 만든
.srh파일에서 로드됨), - 세션 워터마크 (
DocOptions.Watermark에서 제공).
수명
세션은 슬라이딩 윈도우 방식으로 만료됩니다: DocOptions.TimeOut 분(기본값 60)이며, 토큰을 제시하는 모든 요청마다 재설정됩니다. 세션이 종료될 때(만료 또는 CloseDocument(token)에 의해) 해당 문서 엔진이 해제되고 메모리가 즉시 해제됩니다.
// A short-lived session for a one-shot preview
var token = await viewer.OpenDocumentAsync(path, new DocOptions { TimeOut = 10 });만료된 토큰을 포함한 요청은 Document session not found. Please re-open document.라는 오류 이미지를 반환합니다. 페이지는 새 토큰을 얻기 위해 문서를 다시 열어야 합니다. 단일 서버에서는 애플리케이션 풀을 재활용하면 모든 세션이 종료됩니다.
페이지는 해당 세션에만 제공됩니다
UnsafeMode = false(기본값)인 경우, 문서를 열면 문서를 연 요청의 ASP.NET 세션에 secure-{token} 항목을 기록하여 접근 권한을 부여합니다. DocImage.axd는 자체적으로 세션 상태가 필요하며, 해당 항목을 보유한 세션일 때만 페이지를 제공합니다. 동일한 토큰을 제시하는 다른 브라우저는 You Are Not Authorized To View This Page.라는 오류 이미지를 받게 됩니다.
Doconut.DoconutHost.Initialize(options =>
{
// false (the default): DocImage.axd serves a page only to the ASP.NET session that opened
// the document. The handler asks for session state itself; it only needs the site not to
// turn session state off in Web.config.
options.UnsafeMode = false;
});세 가지 실용적인 결과:
- 열기 엔드포인트는 세션 상태가 필요합니다. MVC 컨트롤러와 Web Forms 페이지는 기본적으로 세션을 가지고 있습니다. 사용자 정의
IHttpHandler는System.Web.SessionState.IRequiresSessionState를 구현하지 않으면 세션을 갖지 않습니다. 세션 없이 열기를 수행하면 부여할 것이 없으므로 뷰어는 모든 페이지에서 "You Are Not Authorized To View This Page."을 표시합니다. - 세션 상태는 켜져 있어야 합니다.
Web.config의<sessionState mode="Off" />설정은 부여와 검사를 모두 비활성화하며, 모든 페이지가 거부됩니다. - 브라우저는 세션 쿠키를 전송해야 합니다. 위젯의 요청은 동일 출처이므로 자동으로
ASP.NET_SessionId를 포함합니다. 쿠키 저장소가 없는 클라이언트(스크립트, 서버 간 호출, 쿠키를 제거하는 크로스 오리진 설정)는 거부됩니다. 이것이 기능이 정상 작동하는 이유입니다.
UnsafeMode = true로 설정하면 검사가 비활성화되어 토큰을 포함한 모든 요청이 처리됩니다. 이는 모든 문서에 적용되는 전역 스위치이며 문서별로 재정의할 수 없습니다. false 상태로 유지하십시오.
폐기
CloseDocument(token)은 메모리를 해제하는 것 이상을 수행합니다: 현재 요청의 세션에서 secure-{token} 항목을 제거하고 토큰을 폐기하여, 폐기된 토큰은 즉시 거부됩니다.
웹 팜: 서명된 티켓
팜 환경에서는 다음 요청이 문서를 한 번도 본 적이 없는 서버, 다른 워커 프로세스, 자체 ASP.NET 세션을 가진 서버에 도달할 수 있습니다. 세션 부여는 이를 따라가지 못합니다. 분산 모드는 이를 브라우저에 바인딩된 서명된 티켓으로 대체합니다: 모든 노드는 문서 세션을 위한 하나의 저장소와 하나의 서명 키를 공유하며, DocImage.axd는 해당 티켓이 토큰, 브라우저, 그리고 사용자가 로그인된 경우 해당 사용자에 대해 유효할 때 요청을 허용합니다.
설정은 모든 노드에서 동일합니다:
// Global.asax.cs - Application_Start
Doconut.DoconutHost.Initialize(
options => options.UnsafeMode = false, // the ticket check only runs when this is false
services => services.AddDoconutDistributed(d =>
{
d.Store = CloudLocation.FileShare;
d.FileShareRootPath = @"\\fileserver\doconut-shared"; // a folder every node can reach
d.SigningKey = farmKey; // at least 32 bytes, the SAME on every node
}));열기 엔드포인트는 문서를 열기 전에 티켓을 브라우저에 바인딩하고, 토큰과 함께 티켓을 반환합니다:
DocOptions.BrowserId = DoconutFarmBinding.EnsureBrowserId(System.Web.HttpContext.Current, securityOptions)를 설정합니다 — 이 메서드는 티켓에 연결된doconut-client쿠키를 발급합니다 — 그리고DocOptions.UserId = DoconutFarmBinding.ResolveUserId(System.Web.HttpContext.Current)를 설정합니다;OpenDocumentAsync호출 후, 토큰과 함께viewer.AccessToken을 반환합니다;- 페이지에서 두 값을 위젯에 전달합니다:
objViewer.View(token, access).
Doconut.MvcSample.WebFarm 샘플 패키지에 포함된 예제는 완전하고 실행 가능한 팜 노드이며, 그 옆에 있는 마이그레이션 가이드는 각 단계를 설명합니다.
서명 키를 소스 컨트롤에 포함시키지 마십시오: 이 키는 티켓에 서명하고 공유 저장소의 문서를 암호화합니다. 다른 키를 가진 노드는 다른 노드가 발행한 모든 티켓을 거부합니다.
실제 브라우저나 쿠키를 유지하는 스크립트를 사용해 팜을 테스트하십시오. doconut-client 쿠키가 없는 클라이언트는 401 응답을 받지 않고, 상태 200과 함께 "not authorized" 오류 이미지를 받으며, 크기는 약 2KB입니다. 실제 페이지는 수십에서 수백 KB에 이릅니다.
운영 체크리스트
UnsafeMode = false(기본값)를 유지합니다.- 세션 상태가 있는 요청에서 문서를 열고, 세션 상태를 끄지 않도록 합니다.
- 세션 쿠키가
DocImage.axd에 도달하도록 확인합니다(동일 출처, HTTPS, 허용되는SameSite정책). - 팜에서는 모든 노드가 공유하는 하나의 서명 키를 사용하여 분산 모드를 사용합니다.
- 사용자가 문서를 떠날 때
CloseDocument를 호출합니다 — 메모리와 보안 모두에 이점이 있습니다. - 토큰을 절대 로그에 기록하거나 공유하지 마십시오; 단명한 자격 증명으로 취급합니다.
이 페이지가 도움이 되었나요?