Συνεδρίες & Ασφάλεια
Συνεδρίες εγγράφων και έλεγχος πρόσβασης
Ένα διακριτικό Doconut είναι ισχυρό: όποιος το παρουσιάσει θα μπορούσε να ζητήσει κάθε σελίδα του εγγράφου εάν δεν ήταν δεσμευμένο στη συνεδρία ανοίγματος. Αυτή η σελίδα εξηγεί τι περιέχει μια συνεδρία, πόσο διαρκεί και τους ελέγχους που ενεργοποιεί από προεπιλογή το UseDoconut().
Τι περιέχει μια συνεδρία εγγράφου
Κάθε επιτυχής OpenDocumentAsync δημιουργεί μια συνεδρία στο IMemoryCache:
- το φορτωμένο πρόγραμμα προβολής μορφής (η παρουσία του μηχανήματος εγγράφου που κρατά το αναλυμένο έγγραφο),
- κατά-σελίδα κατάσταση — περιστροφή, αναστροφές και δεδομένα σχολίων που ο χρήστης εφαρμόζει στο widget,
- το προαιρετικό ευρετήριο αναζήτησης, που δημιουργείται αργά στην πρώτη αναζήτηση (ή φορτώνεται από ένα προ-δημιουργημένο αρχείο
.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 του HTTP αιτήματος που το άνοιξε, γράφοντας έναν δείκτη secure-{token} σε αυτή τη συνεδρία. Το middleware Doconut τότε αρνείται να σερβίρει σελίδες σε οποιαδήποτε άλλη συνεδρία προγράμματος περιήγησης:
- Διαφορετικό πρόγραμμα περιήγησης/συνεδρία που παρουσιάζει κλεμμένο διακριτικό → εικόνα σφάλματος
You Are Not Authorized To View This Page. - Middleware συνεδρίας δεν έχει εγγραφεί → HTTP 500
Session middleware not configured. Call UseSession() before UseDoconut().
Αυτό είναι ο λόγος που το Quick Start απαιτεί AddSession() + app.UseSession() πριν από το κλάδο Doconut. Δύο πρακτικές συνέπειες:
- Ο πελάτης πρέπει να στέλνει το cookie συνεδρίας ASP.NET με τα αιτήματα σελίδας. Ρυθμίσεις cross-origin που αφαιρούν cookies (ή ένας πελάτης API χωρίς cookie jar) θα αποτύχουν στον έλεγχο — αυτό είναι η λειτουργία που δουλεύει, όχι σφάλμα.
options.UnsafeMode = trueαπενεργοποιεί πλήρως τη σύνδεση. Υπάρχει για ελεγχόμενα σενάρια· αφήστε τοfalseστην παραγωγή σε έναν μοναδικό κόμβο.
Σημειώστε την ορθογραφία. Η προηγούμενη βιβλιοθήκη .NET Standard ονόμαζε αυτήν την ιδιότητα UnSafeMode και τη διέθετε στο middleware· εδώ είναι UnsafeMode και ορίζεται μία φορά μέσα στο AddDoconut().
Η σύνδεση διακριτικού ελέγχεται αποκλειστικά από αυτόν τον παγκόσμιο διακόπτη UnsafeMode — είναι ενεργοποιημένο από προεπιλογή (UnsafeMode = false) και εφαρμόζεται σε κάθε συνεδρία. Δεν υπάρχει δυνατότητα εξαίρεσης ανά έγγραφο· ορίζοντας UnsafeMode = true απενεργοποιεί τη σύνδεση παγκοσμίως.
Δικαιώματα πρόσβασης και πιστοποιημένοι χρήστες
Όταν το UnsafeMode είναι false, το UseDoconut() εισάγει αυτόματα το middleware πρόσβασης εγγράφου πριν από το middleware σελίδας. Μην το καταχωρίσετε δεύτερη φορά. Όταν ένα αίτημα μεταφέρει ένα διακριτικό, αναζητά το δικαίωμα πρόσβασης που καταγράφηκε όταν το έγγραφο ανοίχθηκε και εξουσιοδοτεί μόνο εάν ισχύουν όλα τα παρακάτω:
- υπάρχει δικαίωμα για το διακριτικό,
- δεν έχει λήξει (διάρκεια δικαιώματος = το
TimeOutτου εγγράφου), - το ID της ASP.NET συνεδρίας του αιτούντος ταιριάζει με αυτό που άνοιξε το έγγραφο,
- εάν ο ανοίγων ήταν πιστοποιημένος, το
NameIdentifierclaim του αιτούντος χρήστη ταιριάζει επίσης.
Οι αποτυχίες επιστρέφουν 403 — ως εικόνα PNG σφάλματος για αιτήματα σελίδας/μικρογραφίας, αλλιώς ως απλό κείμενο. Το μήνυμα και το κλειδί ερωτήματος διακριτικού προέρχονται από το DocumentSecurityOptions (TokenQueryKey, προεπιλογή "token"· UnauthorizedMessage, προεπιλογή "You Are Not Authorized To View This Page."). Διαμορφώστε αυτές τις επιλογές μέσω ASP.NET Core DI πριν δημιουργήσετε την εφαρμογή. Εάν η κατάσταση συνεδρίας δεν είναι διαθέσιμη, το middleware κλείνει με 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.";
});Το βασικό middleware σελίδας στη συνέχεια επαληθεύει τον δείκτη secure-{token} της συνεδρίας πριν σερβίρει το έγγραφο. Με UnsafeMode = true, το UseDoconut() παραλείπει το middleware πρόσβασης και ο έλεγχος του βασικού δείκτη επίσης απενεργοποιείται.
Ασφάλεια σε πολλούς κόμβους
Τα διακριτικά δεσμευμένα σε συνεδρία υποθέτουν ότι ο κόμβος που σερβίρει μια σελίδα είδε επίσης το αίτημα που άνοιξε το έγγραφο. Αυτή η υπόθεση δεν ισχύει όταν πολλοί κόμβοι σερβίρουν τα ίδια έγγραφα από κοινόχρηστη αποθήκευση: ένα αίτημα σελίδας μπορεί να καταλήξει σε κόμβο που δεν είδε ποτέ το άνοιγμα, και ο έλεγχος ανά συνεδρία το απορρίπτει.
Η λύση δεν είναι να αφήσουμε τα έγγραφα ακατάστατα. Χρησιμοποιήστε υπογεγραμμένα εισιτήρια πρόσβασης μέσω του AddDoconutDistributedDocumentSecurity(...), που αντικαθιστά τον έλεγχο συνεδρίας με ένα διαπιστευτήριο που κάθε κόμβος μπορεί να επαληθεύσει ανεξάρτητα. Η πλήρης διάταξη περιγράφεται στο Διανεμημένες Αναπτύξεις.
Ανάκληση
CloseDocument(token) δεν απλώς ελευθερώνει μνήμη — αφαιρεί επίσης τον δείκτη secure-{token} και ανακαλεί το δικαίωμα πρόσβασης, έτσι ένα κλειστό διακριτικό είναι άμεσα άχρηστο και στα δύο επίπεδα ασφαλείας.
Λίστα ελέγχου για παραγωγή
- Διατηρήστε το
UnsafeMode = false(η προεπιλογή) σε έναν μοναδικό κόμβο — αυτός ο παγκόσμιος διακόπτης είναι αυτός που συνδέει τα διακριτικά με τις συνεδρίες. - Εγγραφείτε το
AddDistributedMemoryCache()(οι εφαρμογές MVC και Razor Pages το έχουν ήδη) και τοAddSession(), και καλέστε τοapp.UseSession()πριν από το κλάδο middleware Doconut. - Βεβαιωθείτε ότι η πολιτική cookie συνεδρίας σας επιτρέπει στα αιτήματα του widget να μεταφέρουν το cookie (
SameSite, HTTPS). - Χρησιμοποιήστε το
CloseDocumentόταν ο χρήστης αφήνει το έγγραφο — ωφελούνται η μνήμη και η ασφάλεια. - Ποτέ μην καταγράφετε ή μοιράζεστε διακριτικά· αντιμετωπίζετε τα ως βραχύβια διαπιστευτήρια.
- Σερβίρετε από κοινόχρηστη αποθήκευση; Μεταβείτε σε υπογεγραμμένα εισιτήρια πρόσβασης αντί να αποδέχεστε ακατάστατα έγγραφα.
Ήταν αυτή η σελίδα χρήσιμη;