C# API调用在用户没有';T
Windows服务出现问题,需要监视/访问一组文件夹,并在这些文件夹之间移动文件 这里有一些过去使用过的样板代码,用于检查给定文件夹中给定用户的特定粒度权限。奇怪的是,我通过测试发现,如果我手动拒绝服务运行帐户在该文件夹上的所有权限,然后运行代码,它会报告一切正常,并且用户确实拥有这些权限,尽管很明显(并且可以证明)他没有 起初我认为这可能是因为该服务是在本地系统帐户下运行的,但如果它与NetworkService以及本地用户帐户一起运行,则会出现同样的问题。这是在Windows7/2008R2上 样板法:C# API调用在用户没有';T,c#,windows,file,permissions,user-accounts,C#,Windows,File,Permissions,User Accounts,Windows服务出现问题,需要监视/访问一组文件夹,并在这些文件夹之间移动文件 这里有一些过去使用过的样板代码,用于检查给定文件夹中给定用户的特定粒度权限。奇怪的是,我通过测试发现,如果我手动拒绝服务运行帐户在该文件夹上的所有权限,然后运行代码,它会报告一切正常,并且用户确实拥有这些权限,尽管很明显(并且可以证明)他没有 起初我认为这可能是因为该服务是在本地系统帐户下运行的,但如果它与NetworkService以及本地用户帐户一起运行,则会出现同样的问题。这是在Windows7/2008R2
public static void ValidateFolderPermissions(WindowsIdentity userId, string folder, FileSystemRights[] requiredAccessRights)
{
SecurityIdentifier secId;
StringBuilder sb = new StringBuilder();
bool permissionsAreSufficient = false;
bool notAuthorized = false;
String errorMsg = String.Empty;
IdentityReferenceCollection irc = userId.Groups;
foreach (IdentityReference ir in irc)
{
secId = ir.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier;
try
{
DirectoryInfo dInfo = new DirectoryInfo(folder);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
AuthorizationRuleCollection rules = dSecurity.GetAccessRules(true, true, typeof(SecurityIdentifier));
foreach (FileSystemAccessRule ar in rules)
{
if (secId.CompareTo(ar.IdentityReference as SecurityIdentifier) == 0)
{
sb.AppendLine(ar.FileSystemRights.ToString());
foreach (FileSystemRights right in requiredAccessRights)
{
if (right == ar.FileSystemRights)
{
permissionsAreSufficient = true;
break;
}
}
}
}
}
catch (UnauthorizedAccessException)
{
notAuthorized = true;
errorMsg = "user not authorized";
}
catch (SecurityException)
{
// If we failed authorization do not update error
if (!notAuthorized)
errorMsg = "security error";
}
catch (Exception)
{
// If we failed authorization do not update error
if (!notAuthorized)
errorMsg = "invalid folder or folder not accessible";
}
}
if (!permissionsAreSufficient)
{
if (!String.IsNullOrEmpty(errorMsg))
throw new Exception(String.Format("User {0} does not have required access to folder {1}. The error is {2}.", userId.Name, folder, errorMsg));
else
throw new Exception(String.Format("User {0} does not have required access rights to folder {1}.", userId.Name, folder));
}
}
以及调用代码段:
FileSystemRights[] requireAccessRights =
{
FileSystemRights.Delete,
FileSystemRights.Read,
FileSystemRights.FullControl
};
try
{
FolderPermissionValidator.ValidateFolderPermissions(WindowsIdentity.GetCurrent(), inputFolder, requireAccessRights);
Log.Debug("In ServiceConfigurationValidator: {0}, {1}", WindowsIdentity.GetCurrent().Name, inputFolder);
}
catch (Exception ex)
{
Log.Debug("Throwing exception {0}", ex.Message);
}
我在ValidateFolderPermissions中没有看到任何东西可以在检查允许的权限之前检查拒绝。如果拒绝条目阻止访问,那么任何数量的允许条目都不能覆盖它。我在ValidateFolderPermissions中没有看到任何内容可以在检查允许的权限之前检查拒绝。如果拒绝条目阻止访问,那么任何数量的允许条目都不能覆盖它。此代码将ACL中的条目作为FileSystemAccessRule对象枚举,但不检查AccessControlType是允许还是拒绝 我还注意到,如果任何ACE与requiredAccessRights数组的任何元素完全匹配,则逻辑返回true;我怀疑预期的行为是,如果所有指定的权限都存在,则返回true。如果仅存在一些请求的权限,这可能会导致误报,但由于它只查找精确匹配,因此也可能导致误报,例如,如果ACE实际提供的权限多于请求的权限。(不过,在给出的示例中不是这样的问题,因为您要求完全控制。) 另一个缺陷是,它只检查与用户所属组匹配的访问条目;将忽略用户帐户本身的访问条目。(我不确定WindowsIdentity.Groups的行为是什么,它是用于非实际用户帐户的安全原语,如SYSTEM和NetworkService,尽管听起来该部分工作正常。)
请注意,因为很难正确处理所有可能的情况(例如,考虑每个人或服务的访问控制条目)如果管理员错误地报告帐户没有必要的访问权限,那么允许管理员覆盖检查是明智的。此代码将ACL中的条目枚举为FileSystemAccessRule对象,但不必检查AccessControlType是allow还是deny 我还注意到,如果任何ACE与requiredAccessRights数组的任何元素完全匹配,则逻辑返回true;我怀疑预期的行为是,如果所有指定的权限都存在,则返回true。如果仅存在一些请求的权限,这可能会导致误报,但由于它只查找精确匹配,因此也可能导致误报,例如,如果ACE实际提供的权限多于请求的权限。(不过,在给出的示例中不是这样的问题,因为您要求完全控制。) 另一个缺陷是,它只检查与用户所属组匹配的访问条目;将忽略用户帐户本身的访问条目。(我不确定WindowsIdentity.Groups的行为是什么,它是用于非实际用户帐户的安全原语,如SYSTEM和NetworkService,尽管听起来该部分工作正常。)
请注意,由于很难正确处理所有可能的情况(例如,考虑每个人或服务的访问控制条目),因此如果管理员错误地报告帐户没有必要的访问权限,则允许管理员覆盖检查是明智的。有一个通用的“目录存在”在代码段中未包含的ValidateFolderPermissions调用之前检查my bad。在代码段中未包含的ValidateFolderPermissions调用之前检查my bad。这些都是有用的建议,谢谢。我确实发现,对于标准用户,此函数可以正确报告权限,但即使我们拒绝该用户访问,管理用户也会报告为具有访问权限。不确定这是否是因为管理员用户理论上可以控制文件或文件夹,而不考虑实际用户权限。如果您的意思是明确拒绝管理员用户访问(使用拒绝条目)那只是因为函数将拒绝条目视为允许条目。奇怪的是,这包含了允许/拒绝检查。如果找到拒绝条目,您是否记得停止查找?通常会有一个拒绝条目和一个允许条目,第一个出现的条目(应该始终是拒绝条目)优先。这些都是有用的建议,谢谢。我确实发现,对于标准用户,此函数可以正确报告权限,但即使我们拒绝该用户访问,管理用户也会报告为具有访问权限。不确定这是否是因为管理员用户理论上可以控制文件或文件夹,而不考虑实际用户权限。如果您的意思是明确拒绝管理员用户访问(使用拒绝条目)那只是因为函数将拒绝条目视为允许条目。奇怪的是,这包含了允许/拒绝检查。如果找到拒绝条目,您是否记得停止查找?通常会有一个拒绝条目和一个允许条目,第一个出现的条目(应该是