The current file handler used the application pool account to access file shares on the network. However, the client waned to extend the file handler to use the share's effective rights with the current logged in user. The application would construct the URLs on the page in the following format:
http://sharepointsite/site1/filehandler.ashx?\\networkshare\sharename\1.pdf
Since I could not impersonate the current logged in user, I had to figure out if the user had access to the share or not within the file handler.
The helper class would take a string
of the current user in the format of "domain\username" and a string
of the share name. It would then find all the SIDs of the user and store them in a string
array. Next, it would find all the grant and deny SIDs on the file share. Finally, it will compare the two and send a bool
back if the user could see the file or not.
public static class FileSystemRightsEx
{
public static bool HasRights(this FileSystemRights rights, FileSystemRights testRights)
{
return (rights & testRights) == testRights;
}
}
public static class FileSystemEffectiveRights
{
public static FileSystemRights GetRights(string userName, string path)
{
ULSLoggingService.LogUITrace("Trying to get rights for the path.");
if (string.IsNullOrEmpty(userName))
{
throw new ArgumentException("userName");
}
if (!Directory.Exists(path) && !File.Exists(path))
{
throw new ArgumentException(string.Format("path: {0}", path));
}
return GetEffectiveRights(userName, path);
}
private static FileSystemRights GetEffectiveRights(string userName, string path)
{
FileSystemAccessRule[] accessRules = GetAccessRulesArray(userName, path);
FileSystemRights denyRights = 0;
FileSystemRights allowRights = 0;
for (int index = 0, total = accessRules.Length; index < total; index++)
{
FileSystemAccessRule rule = accessRules[index];
if (rule.AccessControlType == AccessControlType.Deny)
{
denyRights |= rule.FileSystemRights;
}
else
{
allowRights |= rule.FileSystemRights;
}
}
return (allowRights | denyRights) ^ denyRights;
}
private static FileSystemAccessRule[] GetAccessRulesArray(string userName, string path)
{
ULSLoggingService.LogUITrace(string.Format("Trying to get access rules array
for user '{0}' and path '{1}'.", userName, path));
AuthorizationRuleCollection authorizationRules =
(new FileInfo(path)).GetAccessControl().GetAccessRules
(true, true, typeof(SecurityIdentifier));
foreach (AuthorizationRule rule in authorizationRules)
{
ULSLoggingService.LogUITrace(string.Format("FileSystem Rule name: '{0}'",
rule.IdentityReference.Translate(typeof(NTAccount)).Value));
}
string[] sids = GetSecurityIdentifierArray(userName);
return (from rule in authorizationRules.Cast<FileSystemAccessRule>()
where sids.Contains(rule.IdentityReference.Value)
select rule).ToArray();
}
private static string[] GetSecurityIdentifierArray(string userName)
{
PrincipalContext pc = new PrincipalContext(ContextType.Domain);
UserPrincipal user = new UserPrincipal(pc) { SamAccountName = userName };
PrincipalSearcher searcher = new PrincipalSearcher { QueryFilter = user };
user = searcher.FindOne() as UserPrincipal;
if (user == null)
{
throw new ApplicationException(string.Format("Invalid User Name: {0}", userName));
}
WindowsIdentity windowsIdentity = new WindowsIdentity(user.UserPrincipalName);
string[] sids = new string[windowsIdentity.Groups.Count + 1];
sids[0] = windowsIdentity.User.Value;
for (int index = 1, total = windowsIdentity.Groups.Count; index < total; index++)
{
sids[index] = windowsIdentity.Groups[index].Value;
try
{
ULSLoggingService.LogUITrace("User:" + userName + "User Group:" +
windowsIdentity.Groups[index].Translate(typeof(NTAccount)).Value);
}
catch (Exception ex)
{
ULSLoggingService.LogUIException("proplem with logging", ex);
}
}
return sids;
}
}
CodeProject
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.