あなたはなりすましを調べたいと思うでしょう。アプリケーションで別のユーザーの下でコードを実行できます。アプリケーションでコードを実行するサーバーにアカウントを設定してみてください。
このようにすることは、コードが 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 サーバー側サービスを実行します。