授予WPF应用程序访问共享驱动器的权限,但不允许用户访问

时间:2013-01-30 23:42:48

标签: .net

我有一个WPF应用程序,它将为我们公司的用户提供一种下载和上传文件到Windows服务器上的目录的方法。该应用程序将安装在每个公司成员自己的机器上。

我们希望用户无法直接访问文件浏览器中的目录,因此他们无法访问:" \ fileserver \ files"乱七八糟的。他们只能使用该应用程序上传/下载文件。

为这种情况设置权限的最佳方法是什么?我们可以在服务器上创建用户并让应用程序保存该用户的凭据吗?

1 个答案:

答案 0 :(得分:0)

你想要考虑模仿。您可以让您的应用程序在另一个用户下执行代码。尝试在您希望应用程序执行代码的服务器上设置一个帐户。

这样做意味着您的代码仅在using语句中模拟用户,而不是作为应用程序整个生命周期的其他用户运行。

此类支持跨域模拟以及相同的域。

C#    
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace Utils
{
    public class dvImpersonator : IDisposable
    {
        private WindowsImpersonationContext ImpersonationContext = null;
        enum LogonType
        {
            Interactive = 2,
            Network = 3,
            Batch = 4,
            Service = 5,
            Unlock = 7,
            NetworkClearText = 8,
            NewCredentials = 9
        }
        enum LogonProvider
        {
            Default = 0,
            WinNT35 = 1,
            WinNT40 = 2,
            WinNT50 = 3
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="domainName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public bool LogOn(string _UserName, string _DomainName, string _Password)
        {
            return ImpersonateValidUser(_UserName, _DomainName, _Password, LOGON32_LOGON_INTERACTIVE);
        }

        public bool CrossDomainLogOn(string _UserName, string _DomainName, string _Password)
        {
            return ImpersonateValidUserCrossDomain(_UserName, _DomainName, _Password);
        }

        public void Dispose()
        {
            UndoImpersonation();
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern int LogonUserA(
                      string lpszUserName,
                      string lpszDomain,
                      string lpszPassword,
                      int dwLogonType,
                      int dwLogonProvider,
                      ref IntPtr phToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int DuplicateToken(
               IntPtr hToken,
               int impersonationLevel,
               ref IntPtr hNewToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool RevertToSelf();


        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern bool CloseHandle(
                 IntPtr handle);


        private const int LOGON32_PROVIDER_DEFAULT = 0;
        private const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
        private const int LOGON32_LOGON_INTERACTIVE = 2;


        /// <summary>
        /// Does the actual impersonation.
        /// </summary>
        /// <param name="userName">The name of the user to act as.</param>
        /// <param name="domainName">The domain name of the user to act as.</param>
        /// <param name="password">The password of the user to act as.</param>
        private bool ImpersonateValidUser(string _UserName, string _Domain, string _Password, int provider)
        {
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;
            int iRet = 0;
            if (RevertToSelf())
            {
                //Console.WriteLine("here 1");
                if ((iRet = LogonUserA(_UserName, _Domain, _Password,
                    provider, LOGON32_PROVIDER_DEFAULT, ref token)) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        ImpersonationContext = tempWindowsIdentity.Impersonate();
                        if (ImpersonationContext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                            return true;
                        }
                    }


                }
                //Console.WriteLine("iret " + iRet);
            }
            if (token != IntPtr.Zero)
                CloseHandle(token);
            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);
            return false;

        }

        /// <summary>
        /// Does the actual impersonation.
        /// </summary>
        /// <param name="userName">The name of the user to act as.</param>
        /// <param name="domainName">The domain name of the user to act as.</param>
        /// <param name="password">The password of the user to act as.</param>
        private bool ImpersonateValidUserCrossDomain(string _UserName, string _Domain, string _Password)
        {
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;
            int iRet = 0;
            if (RevertToSelf())
            {
                //Console.WriteLine("here 1");
                if ((iRet = LogonUserA(_UserName, _Domain, _Password,
                    (int)LogonType.NewCredentials, (int)LogonProvider.WinNT50, ref token)) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        ImpersonationContext = tempWindowsIdentity.Impersonate();
                        if (ImpersonationContext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                            return true;
                        }
                    }


                }
                //Console.WriteLine("iret " + iRet);
            }
            if (token != IntPtr.Zero)
                CloseHandle(token);
            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);
            return false;

        }


        /// <summary>
        /// Reverts the impersonation.
        /// </summary>
        private void UndoImpersonation()
        {
            if (ImpersonationContext != null)
            {
                ImpersonationContext.Undo();
            }
        }

    }



}

样本用法:

C#

using (var LogOn = new Utils.dvImpersonator())
{
    LogOn.CrossDomainLogOn(this.oConfig.User, this.oConfig.Domain, this.oConfig.Password);

       //Code to Execute as other users
}

您还可以拥有一个服务器端WCF服务,该服务具有上载方法和下载方法。然后在WPF应用程序中使用WCF服务,并使您的WCF服务器端服务在可访问服务器的帐户下运行。