如果Windows服务需要监视/访问一组文件夹,并在这些文件夹之间移动文件时遇到问题。API调用要求用户具有文件夹权限时
过去已经使用了一些样板代码,它将检查给定文件夹中给定用户的特定粒度权限。奇怪的是,我通过测试发现,如果手动拒绝该服务运行所在的帐户对该文件夹的所有权限,然后运行代码,则会报告一切正常,并且用户实际上拥有这些权限,即使它很明显(并且可证明)他没有。
起初我以为这可能是因为该服务在本地系统帐户下运行,但如果与NetworkService以及本地用户帐户一起运行,则会出现同样的问题。这在Windows 7/2008 R2上。
样板方法:
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);
}
这些是有益的建议,谢谢。我发现的一件事是,对于标准用户,这个函数的权限被正确报告,但即使我们拒绝该用户访问,管理用户也被报告具有访问权限。不知道这是否是因为管理员用户理论上可以控制文件或文件夹,而不管用户的实际权限与否。 – bleggett
如果您的意思是您明确拒绝管理员用户访问(使用拒绝条目),那只是因为该功能将拒绝条目视为允许条目。 –
这是与一个允许/拒绝检查,足够奇怪。 – bleggett