Asp.net Web服务需要返回Windows Principal的NTFS文件权限而不是服务本身

时间:2016-04-01 19:14:16

标签: c# .net asp.net-mvc windows-authentication ntfs

我们正在运行一个ASP.net Web服务,该服务需要能够根据用户的NTFS权限或者他/她是AD组来上传,重命名,删除和查看中央服务器上的文件。成员。 AD用户可以远程访问此服务以及本地访问此服务。我们正在使用Windows身份验证(而不是Kerberos)。

我已经编写了一些代码来检查读取和写入访问的NTFS权限(代码位于帖子的底部)。它仅向他们显示他们已读取数据访问权限的文件夹,并为他们没有写入数据访问权限的人隐藏上传/编辑/删除选项。当我在我的机器上运行localhost时,它运行良好。 问题当我发布到QA服务器时,我获得了服务的权限,而不是远程用户。下面的文章解释了为什么会发生这种情况。不幸的是,我们目前无法使用Kerberos身份验证。

我几乎没有想法。我没有考虑过的任何选项?

https://msdn.microsoft.com/en-us/library/ff647405.aspx 使用Windows身份验证模拟 通过使用模拟,ASP.NET应用程序可以使用经过身份验证的用户的身份或固定的Windows身份执行代码或访问资源。 通常在您启用模拟时创建的标准模拟级模拟令牌允许您仅访问本地资源。 为了能够访问远程网络资源,您需要委托级令牌。要在模拟时生成委托级令牌,您需要使用Kerberos身份验证,并且您的进程帐户需要在Active Directory中标记为受信任以进行委派。

我在我的Web.config中尝试<identity impersonate="true" />,但收到此错误System.Data.SqlClient.SqlException: Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.

我的下一次尝试是在我的控制器上的HttpGet方法中进行临时模拟。

IIdentity WinId = User.Identity;
WindowsIdentity wi = (WindowsIdentity)WinId;
WindowsImpersonationContext wic = wi.Impersonate();
  try
  { //GET Method of ActionResult
    var user = WindowsIdentity.GetCurrent().User;
    var userName = user.Translate(typeof(System.Security.Principal.NTAccount)).ToString();
  }

检索userName显示我可以成功模拟用户,但我仍然只拥有该服务的文件权限。

这是检查文件夹级别访问的NTFS权限的代码。

    public static bool CheckPermission(string path, string accessType)
    {
        bool hasReadAccess = false;
        bool hasWriteAccess = false;
        try
        {
            DirectoryInfo dir = new DirectoryInfo(path);
            DirectorySecurity acl = dir.GetAccessControl();
            AuthorizationRuleCollection rules = acl.GetAccessRules(true, true, typeof(SecurityIdentifier));
            WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(currentUser);
            foreach (AuthorizationRule rule in rules)
            {
                FileSystemAccessRule fsAccessRule = rule as FileSystemAccessRule;
                if (fsAccessRule == null)
                    continue;
                if (accessType.ToLower() == "readdata")
                {
                    return hasReadAccess = CheckReadAccess(fsAccessRule, principal);
                }
                if (accessType.ToLower() == "writedata")
                {
                    return hasWriteAccess = CheckWriteAccess(fsAccessRule, principal);
                }
            }
            return hasReadAccess;
        }
        catch (UnauthorizedAccessException)
        {
            return false;
        }
    }

这是我的CheckReadAccess方法。 CheckWriteAccess基本相同。

    public static bool CheckReadAccess(FileSystemAccessRule fsAccessRule, WindowsPrincipal principal)
    {
        bool hasReadAccess = false;

        if ((fsAccessRule.FileSystemRights & FileSystemRights.ReadData) > 0)
        {
            SecurityIdentifier sID = fsAccessRule.IdentityReference as SecurityIdentifier;

            if (sID != null)
            {
                if (principal.IsInRole(sID))
                {
                    if (fsAccessRule.AccessControlType == AccessControlType.Deny)
                    {

                        return hasReadAccess = false;
                    }
                    else if (fsAccessRule.AccessControlType == AccessControlType.Allow)
                    {

                        return hasReadAccess = true;
                    }

                }
            }
        }
        return hasReadAccess;
    }

0 个答案:

没有答案