0

私たちの会社のユーザーに、Windowsサーバー上のディレクトリにファイルをダウンロードおよびアップロードする方法を提供するWPFアプリケーションがあります。アプリケーションは、各企業メンバーのマシンにインストールされます。

ユーザーがファイル ブラウザでディレクトリに直接アクセスできないようにしたいので、単に "\fileserver\files" に移動して混乱することはありません。アプリケーションを使用してファイルをアップロード/ダウンロードすることしかできません。

この状況でアクセス許可を設定する最善の方法は何ですか? サーバー上にユーザーを作成し、アプリにそのユーザーの資格情報を保持させることはできますか?

4

1 に答える 1

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 サーバー側サービスを実行します。

于 2013-01-30T23:52:08.853 に答える