WCF File Repository and Security - Error in permissions on saving file

半腔热情 提交于 2019-12-14 04:00:11

问题


I have a file repository service that for the most part works. The issue is, once I started to implement DirectorySecurity into the methods I ran into issues. The directories create just fine, the assigned accounts to directories are given access, but all permissions end up under "special permissions". That, however, is not the problem. The problem arises when I try to write a new file. I get the following error message:

System.ServiceModel.FaultException'1 ... Access to the path ... is denied.

As I said, the directory structure is created to save the file. The file, however, does not make it into the folder. I do see all my allowed users, and I can place files in there. Again, however, doing so manually in windows I can run .exe files from the directory despite the fact I denied the permission in the AccessControls. Below is an example of the 'Put' method and another method I use to build the DirectorySecurity object.

Questions I have:

  1. Any thoughts on what is going wrong, or advice on security to prevent executable?

  2. Does Visual Studio 2012 need to use a specific "Account" (e.g. NETWORK SERVICES") when running in Debug mode? I did not add that to the permission set.

  3. Is there a timing issue when creating a directory? If so would hit help to Thread.Sleep for a bit to allow Windows to catch up?

  4. Any other advice / things I am missing or did wrong here?

Note on Environment: Windows 7 Ultimate, Visual Studio 2012 (running Windows Form test client via Debug start). The Service is currently installed locally via WAS (running in Services.msc). This is a net.Tcp service with endpoints exposed to client and proxy built manually using ChannelFactory. Get methods seem to work fine. Put methods fail to put the final file into the created directory, and I have concerns that the permissions are actually working correctly.

//----------------------------
//WCF Service - PutText Method
//----------------------------

    //NOTE: dir = virtual directory
        public bool PutTextFile(string dir, string fileName, string data)
        {
            string path;
            string fExt;
            DirectoryInfo d;

            #region Null / value checks
            //...
            #endregion

            //check & enforce file extension
            fExt = Path.GetExtension(fileName).ToLower();
            if (fExt != ".txt" && fExt != ".xml" && fExt != ".csv")
            {
                fileName = Path.GetFileNameWithoutExtension(fileName) + ".txt";
            }

            //check directory exists
            d = new DirectoryInfo(Path.Combine(this._fileRepositoryRoot, dir));//_fileRepositoryRoot is taken from .config
            if (!d.Exists)
            {
                try
                {
                    DirectorySecurity ds = this.CreateDirSecurityObj(); //<-- See method below
                    d.Create(ds);
                }
                catch (Exception e)
                {
            //...
                }
            }

            //complete path
            path = Path.Combine(this._fileRepositoryRoot, dir, fileName);

            try
            {
                using (StreamWriter sw = File.CreateText(path))
                {
                    sw.Write(data);
                }
                return true;
            }
            catch (Exception e)
            {
        //...
            }
        }

//-------------------------
//Directory Security Method
//-------------------------
//NOTE: 
//"private string _myDomain" and "private string _myUserAccount" are pulled from an app.config file

private DirectorySecurity CreateDirSecurityObj()
        {
            System.Security.AccessControl.DirectorySecurity ds = new System.Security.AccessControl.DirectorySecurity();

            //define User rights
            FileSystemRights grantUserRights = FileSystemRights.AppendData;
            grantUserRights |= FileSystemRights.Synchronize;
            grantUserRights |= FileSystemRights.CreateDirectories;
            grantUserRights |= FileSystemRights.CreateFiles;
            grantUserRights |= FileSystemRights.ListDirectory;
            grantUserRights |= FileSystemRights.Read;
            grantUserRights |= FileSystemRights.Write;
            grantUserRights |= FileSystemRights.Delete;

            FileSystemRights denyUserRights = FileSystemRights.ExecuteFile;
            denyUserRights |= FileSystemRights.ChangePermissions;

            //define access rule
            FileSystemAccessRule grantRule_User = new FileSystemAccessRule(Path.Combine(this._myDomain, this._myUserAccount), grantUserRights, AccessControlType.Allow);
            FileSystemAccessRule denyRule_User = new FileSystemAccessRule(Path.Combine(this._myDomain, this._myUserAccount), denyUserRights, AccessControlType.Deny);

            //add access rule
            ds.AddAccessRule(grantRule_User);
            ds.AddAccessRule(denyRule_User);
            ds.AddAccessRule(grantRule_Admin);

            return ds;
        }

UPDATE: I tried adding permissions for "NT AUTHORITY\NETWORK SERVICES" (limited access) and "NT AUTHORITY\SYSTEM" (full access). I still get the same denial message. Turning off the DirectorySecurity practices works fine. This must be a problem with the 'mix' or rules. Repeat attempts fail even when directory is in place.

来源:https://stackoverflow.com/questions/19744058/wcf-file-repository-and-security-error-in-permissions-on-saving-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!