Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια

Αντιγραφή αρχείου σε UNC Path προγραμματιστικά (ASP.NET or just code)

Η αντιγραφή αρχείου σε NAS, προγραμματιστικά (ή εν γένει σε κάποιο UNC location εκτός τοπικού μηχανήματος) είναι μία ανάλογη διαδικασία, όπως αν το κάνουμε μέσω του UI. Θα ανοίγαμε το Run, στην συνέχεια πληκτρολογούμε το unc path. Αν σε εκείνη την τοποθεσία έχουν τεθεί permissions για όλους, τότε το παράθυρο ανοίγει κατευθείαν. Σε αντίθετη περίπτωση θα πρέπει να εισαχθούν τα στοιχεία για να γίνει login ο χρήστης, είτε τοπικός, είτε domain (σε αυτήν την περίπτωση θα πρέπει να εισαχθεί και το domain με τον γνωστό τρόπο domain/username). Τι χρειάζεται όμως για να γίνει προγραμματιστικά η διεργασία και μάλιστα μέσα από κώδικα που εκτελείται στο περιβάλλον του IIS; Τότε αυτό που θέλουμε να κάνουμε λέγεται delegation και υπόκειται στο κεφάλαιο ASP.NET Delegation. Με βάση αυτό μπορεί η ASP.NET να προσπελάσει resources σε απομακρυσμένο σύστημα. Μία ειδική περίπτωση αυτού είναι το ASP.NET Impersonation με το οποίο το σύστημα είναι τοπικό. Mε αυτόν τον τρόπο οι ASP.NET εφαρμογές μπορούν να εκτελέσουν κώδικα κάτω από την ταυτότητα του χρήστη τον οποίο απαιτείται να χρησιμοποιήσουν για την πρόσβαση. Για να γίνει αυτό θα πρέπει τα δύο μηχανήματα να μελετηθούν ως προς το λειτουργικό τους, την ύπαρξη του δικαιώματος για delegation, κτλ. Επίσης θέλει προσοχή κατά το σχεδιασμό μιάς τέτοιας λύσης για λόγους ασφαλείας.

Έστω ότι έχω την περίπτωση που ο IIS τρέχει κάτω από το IUSR_machinename για ανώνυμη πρόσβαση. Αν γνωρίζω από πριν username και password τότε μπορώ ρυθμίζοντας το directive <processModel> να ελέγξω την παραπάνω διαδικασία (βλ. link για asp.net delegation). Στην περίπτωσή μου θέλω να ελέγχω την διαδικασία πλήρως χρησιμοποιώντας το LogonUser API. Θέλω λοιπόν να κάνω ένα συγκεκριμένο account login, όπως έδειξα και νωρίτερα όταν ήθελα να μεταφέρω ένα αρχείο από το ui. Δεν υπάρχει αντίστοιχη μέθοδος όμως (ως Login, αυτούσια), στο .ΝΕΤ και η μόνη μέθοδος που κάνει impersonate είναι η WindowsIdentity.Impersonate (IntPtr), από το System.Security.Principal. Τι είναι το IntPtr; Είναι ένα handle για τον χρήστη του συστήματος και ανακτάται από κλήση σε unmanaged κώδικα μέσω της LogonUser από το advapi32.dll.

Στον κώδικά μου ήθελα να μπορώ να τρέχω ένα File.Copy (ή οτιδήποτε) το οποίο θα εκτελείται με βάση συγκεκριμένα credentials.

Impersonation.Execute(myEntity.NasUser, myEntity.NasPassword, () => { //Copy File to NAS    File.Copy(sourceFile, Path.Combine(myEntity.UploadPath, Path.GetFileName(sourceFile)), true); });

 

#region DllImport         [DllImport("advapi32.dll", SetLastError = true)]         public static extern bool LogonUser(             string lpszUsername,             string lpszDomain,             string lpszPassword,             int dwLogonType,             int dwLogonProvider,             out IntPtr phToken             );         [DllImport("kernel32.dll", CharSet = CharSet.Auto)]         public extern static bool CloseHandle(IntPtr handle); #endregion

 

Έτσι η Execute που έγραψα, χοντρικά ήταν η εξής

public static void Execute(string userName, string domain, string password, Action action)         {             try             {                 bool bImpersonated = LogonUser(                     userName,                     domain,                     password,                     logon32LogonInteractive,                     logon32ProviderDefault,                     out tokenHandle);                 if (bImpersonated == false)                 {                     throw new Win32Exception(Marshal.GetLastWin32Error());                 }                 WindowsIdentity newId = new WindowsIdentity(tokenHandle);                 impersonatedUser = newId.Impersonate();                 action();             }             catch (Exception ex)             {                 throw ex;             }             finally             {                 if (impersonation != null)                     impersonation.Dispose();             }         }

Αξίζει να σημειώσουμε ότι στο τέλος θα πρέπει οπωσδήποτε να επαναφέρεται το process identity στο προηγούμενο (μέσω τη undo), γιατί θα υπάρξει πρόβλημα στις περαιτέρω ενέργειες

public void Dispose() {     // Stop impersonating the user.     if (impersonatedUser != null)         impersonatedUser.Undo();     // close handle     if (tokenHandle != IntPtr.Zero)         CloseHandle(tokenHandle); }

Τέλος η παραπάνω διεργασία χρειάζεται full trust (PermissionSetAttribute)

Posted: Πέμπτη, 14 Ιανουαρίου 2010 11:02 μμ από το μέλος George J. Capnias
Δημοσίευση στην κατηγορία: , ,

Σχόλια:

Χωρίς Σχόλια

Ποιά είναι η άποψή σας για την παραπάνω δημοσίευση;

(απαιτούμενο)

(απαιτούμενο)

(προαιρετικό)

(απαιτούμενο)
ÅéóÜãåôå ôïí êùäéêü:
CAPTCHA Image

Ενημέρωση για Σχόλια

Αν θα θέλατε να λαμβάνετε ένα e-mail όταν γίνονται ανανεώσεις στο περιεχόμενο αυτής της δημοσίευσης, παρακαλούμε γίνετε συνδρομητής εδώ

Παραμείνετε ενήμεροι στα τελευταία σχόλια με την χρήση του αγαπημένου σας RSS Aggregator και συνδρομή στη Τροφοδοσία RSS με σχόλια