سؤال

ولقد تم العمل على مشروع ASP.NET التي يتم الانتقال إلى حفظ الملفات التي يتم تحميلها إلى مشاركة شبكة اتصال. أنا أحسب أنني يمكن أن مجرد استخدام دليل ظاهري ويكون على ما يرام، ولكن لقد كنت تناضل مع أذونات Directory.CreateDirectory.

وكنت قادرا على تحميل الملفات لذلك قررت أن تغيير قانون بلدي لوضع كل شيء في دليل واحد، ولكن هذا يتطلب مني أن الاستفادة من File.Exists لتجنب الكتابة مكررة.

والآن بأنني كل قانون بلدي تحديث، لقد اكتشفت أنه بغض النظر عن ما أقوم به، File.Exists دوما بإرجاع كاذبة (الملف موجود بالتأكيد) عندما كنت اختبار ضد مشاركة شبكة الاتصال.

وأي أفكار؟ أنا قادم إلى النهاية من حبل بلدي مع شبكة سهم.

هل كانت مفيدة؟

المحلول

وعملت مؤخرا على مشروع مماثل جدا مكاني حفظ الملفات إلى مشاركة شبكة اتصال. جهازي كمبيوتر على نفس الشبكة الفرعية، ولكن لا تخضع للرقابة من قبل وحدة تحكم المجال، لذلك لديه كل كمبيوتر انها المستخدمين الخاصة.

وأنا إنشاء مستخدم مع نفس اسم المستخدم وكلمة المرور على كلا الجهازين. ثم أنا خلقت مشاركة شبكة اتصال وتعيين أذونات المجلد / سهم للسماح للقراءة والكتابة للمستخدم.

وثم خلق الطبقة التالية لإدارة التمثيل:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.Text;

namespace MyProject.Business.Web
{
    public class SecurityManager
    {
        #region DLL Imports
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public extern static bool CloseHandle(IntPtr handle);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
        #endregion

        public string Domain { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }

        private WindowsImpersonationContext m_CurrentImpersonationContext;

        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
        public void StartImpersonation()
        {
            const int LOGON32_PROVIDER_DEFAULT = 0;
            const int LOGON32_LOGON_INTERACTIVE = 2;

            IntPtr tokenHandle = IntPtr.Zero;
            IntPtr dupeTokenHandle = IntPtr.Zero;

            // obtain a handle to an access token
            bool wasLogonSuccessful = LogonUser(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);

            if (!wasLogonSuccessful)
                throw new Exception(String.Format("Logon failed with error number {0}", Marshal.GetLastWin32Error()));

            // use the token handle to impersonate the user
            WindowsIdentity newId = new WindowsIdentity(tokenHandle);
            m_CurrentImpersonationContext = newId.Impersonate();

            // free the tokens
            if (tokenHandle != IntPtr.Zero)
                CloseHandle(tokenHandle);
        }
        public void EndImpersonation()
        {
            m_CurrentImpersonationContext.Undo();
        }
    }
}

وبعد ذلك في صفحة ASP.NET فعلت ما يلي:

SecurityManager sm = new SecurityManager();
sm.UserName = ConfigurationManager.AppSettings["UserFileShareUsername"];
sm.Password = ConfigurationManager.AppSettings["UserFileSharePassword"];
sm.StartImpersonation();

if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);

File.Move(sourcePath, destinationPath);

sm.EndImpersonation();

نصائح أخرى

وFile.Exist لا يتحقق في الواقع عن الوجود من ملف. بدلا من ذلك بالتحقق من الوجود من الملفات التي لديك قدر من الوصول إليها. إذا كنت تعرف وجود الملف، والمشكلة المحتملة هي أن لم يكن لديك الوصول إليها.

وربما التعليمات البرمجية التي يتم تشغيل (أي ASP.NET رمز الملقم) يعمل كمستخدم (مثل المستخدم IIS) الذي ليس لديه الإذن للوصول إلى مشاركة شبكة اتصال.

وأعتقد أن ليس من المفترض IIS ليتم تشغيلها كمستخدم عالية priviledged، الذي افتراضيا لديه الإذن لعرض أسهم على الأجهزة الأخرى.

وكنت كثيرا نفس الرمز، ولكن كان صفي تنفيذ واجهة IDisposable، وأضاف أن تراجع () إلى أسلوب التخلص (). هذا الرمز يعمل بشكل جيد، إذا كنت المطور الوحيد استخدامه وسوف تفعل دائما الأشياء بالطريقة الصحيحة، أليس كذلك؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top