この質問は私が尋ねていることですが、答えは_tokenがどのように導出されるかについての詳細を提供しません。 WindowsIdentity.GetCurrent().Token
のみを使用しているようであるため、なりすましは発生しません。
。NETの別のActive Directoryドメインのユーザーを偽装できますか?
この次の質問には矛盾する答えがあり、受け入れられた質問には「自分の問題が他の場所にあるのではないかと疑い始めています」というコメントがあります。役に立たない。
この次の質問は不可能であることを暗示しているようですが、2つのドメインを扱っているため、関連性があるかどうかはわかりません。
私の本当の質問は:
これまでに試したのは、 http://msdn.Microsoft.com/en-us/library/chf6fbt4%28v=VS.80%29.aspx のコードを使用することです
bool returnValue = LogonUser(user, domain, password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);
// after this point, returnValue = false
Win32エラーは
ログオン失敗:不明なユーザー名または不正なパスワード
LOGON_TYPE_NEW_CREDENTIALS
またはLOGON_TYPE_NETWORK
の代わりにLOGON_TYPE_INTERACTIVE
を使用することを提案する投稿はほとんどありません。ドメインに接続されているマシンとドメインに接続されていないマシンでなりすましの問題が発生したため、修正されました。 この投稿 の最後のコードスニペットは、フォレスト全体で偽装が機能することを示していますが、信頼の設定については特に言及していません。したがって、これは試してみる価値があります:
const int LOGON_TYPE_NEW_CREDENTIALS = 9;
const int LOGON32_PROVIDER_WINNT50 = 3;
bool returnValue = LogonUser(user, domain, password,
LOGON_TYPE_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50,
ref tokenHandle);
MSDNによるLOGON_TYPE_NEW_CREDENTIALS
はLOGON32_PROVIDER_WINNT50
を使用する場合にのみ機能します。
これは私のために、完全に機能する例です(もっと多くの人がこれを行うことを望みます):
//logon impersonation
using System.Runtime.InteropServices; // DllImport
using System.Security.Principal; // WindowsImpersonationContext
using System.Security.Permissions; // PermissionSetAttribute
...
class Program {
// obtains user token
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
// closes open handes returned by LogonUser
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
public void DoWorkUnderImpersonation() {
//elevate privileges before doing file copy to handle domain security
WindowsImpersonationContext impersonationContext = null;
IntPtr userHandle = IntPtr.Zero;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_INTERACTIVE = 2;
string domain = ConfigurationManager.AppSettings["ImpersonationDomain"];
string user = ConfigurationManager.AppSettings["ImpersonationUser"];
string password = ConfigurationManager.AppSettings["ImpersonationPassword"];
try {
Console.WriteLine("windows identify before impersonation: " + WindowsIdentity.GetCurrent().Name);
// if domain name was blank, assume local machine
if (domain == "")
domain = System.Environment.MachineName;
// Call LogonUser to get a token for the user
bool loggedOn = LogonUser(user,
domain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref userHandle);
if (!loggedOn) {
Console.WriteLine("Exception impersonating user, error code: " + Marshal.GetLastWin32Error());
return;
}
// Begin impersonating the user
impersonationContext = WindowsIdentity.Impersonate(userHandle);
Console.WriteLine("Main() windows identify after impersonation: " + WindowsIdentity.GetCurrent().Name);
//run the program with elevated privileges (like file copying from a domain server)
DoWork();
} catch (Exception ex) {
Console.WriteLine("Exception impersonating user: " + ex.Message);
} finally {
// Clean up
if (impersonationContext != null) {
impersonationContext.Undo();
}
if (userHandle != IntPtr.Zero) {
CloseHandle(userHandle);
}
}
}
private void DoWork() {
//everything in here has elevated privileges
//example access files on a network share through e$
string[] files = System.IO.Directory.GetFiles(@"\\domainserver\e$\images", "*.jpg");
}
}
私は同じ問題を抱えていました。これを解決したかどうかはわかりませんが、私が本当にやろうとしていたのは、AD資格情報を使用してネットワーク共有にアクセスすることでした。 WNetAddConnection2()
は、その場合に使用する必要があるものです。
私は別のドメインのユーザーを偽装することに成功していますが、2つのドメイン間に設定された信頼でonlyです。
var token = IntPtr.Zero;
var result = LogonUser(userID, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token);
if (result)
{
return WindowsIdentity.Impersonate(token);
}
無効なログイン/パスワードは、DNSサーバーの問題にも関連している可能性があります。ドメイン名に代わりにIPアドレスを指定できるかどうかを確認してください。
SecureStringを使用することをお勧めします。
var password = new SecureString();
var phPassword phPassword = Marshal.SecureStringToGlobalAllocUnicode(password);
IntPtr phUserToken;
LogonUser(username, domain, phPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out phUserToken);
そして:
Marshal.ZeroFreeGlobalAllocUnicode(phPassword);
password.Dispose();
関数定義:
private static extern bool LogonUser(
string pszUserName,
string pszDomain,
IntPtr pszPassword,
int dwLogonType,
int dwLogonProvider,
out IntPtr phToken);